简体   繁体   English

在 c# 中从主列表创建多个唯一条目列表

[英]Create multiple lists of unique entries from master list in c#

I need to process an outbound SMS queue and create batches of messages.我需要处理出站 SMS 队列并创建批量消息。 The queued list might contain multiple messages to the same person.排队列表可能包含发给同一个人的多条消息。 Batches do not allow this, so I need to run through the main outbound queue and create as many batches as necessary to ensure they contain unique entries.批次不允许这样做,因此我需要运行主出站队列并根据需要创建尽可能多的批次以确保它们包含唯一条目。 Example:例子:

Outbound queue = (1,2,3,3,4,5,6,7,7,7,8,8,8,8,9)

results in...结果是...

 batch 1 = (1,2,3,4,5,6,7,8,9)
    batch 2 = (3,7,8)
    batch 3 = (7,8)
batch 4 = (8)

I can easily check for duplicates but I'm looking for a slick way to generate the additional batches.我可以轻松检查重复项,但我正在寻找一种灵活的方式来生成额外的批次。

Thanks!谢谢!

Have a look at this approach using Enumerable.ToLookup and other LINQ methods:使用Enumerable.ToLookup和其他 LINQ 方法查看此方法:

var queues = new int[] { 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 8, 8, 9 };
var lookup = queues.ToLookup(i => i);
int maxCount = lookup.Max(g => g.Count());
List<List<int>> allbatches = Enumerable.Range(1, maxCount)
    .Select(count => lookup.Where(x => x.Count() >= count).Select(x => x.Key).ToList())
    .ToList();

Result is a list which contains four other List<int> :结果是一个包含其他四个List<int>

foreach (List<int> list in allbatches)
    Console.WriteLine(string.Join(",", list));

1, 2, 3, 4, 5, 6, 7, 8, 9
3, 7, 8
8
8

Depending on the specific data structures used, the Linq GroupBy extension method could be used (provided that the queue implements IEnumerable<T> for some type T ) for grouping by the same user;根据使用的特定数据结构,可以使用 Linq GroupBy扩展方法(前提是队列为某些类型T实现了IEnumerable<T> )由同一用户进行分组; afterwards, the groups can be iterated separately.之后,可以分别迭代这些组。

A naive approach would be to walk over the input, creating and filling the batches as you go:一种幼稚的方法是遍历输入,边走边创建和填充批次:

private static List<List<int>> CreateUniqueBatches(List<int> source)
{
    var batches = new List<List<int>>();

    int currentBatch = 0;

    foreach (var i in source)
    {
        // Find the index for the batch that can contain the number `i`
        while (currentBatch < batches.Count && batches[currentBatch].Contains(i))
        {
            currentBatch++;
        }

        if (currentBatch == batches.Count)
        {
            batches.Add(new List<int>());
        }

        batches[currentBatch].Add(i);
        currentBatch = 0;
    }

    return batches;
}

Output:输出:

1, 2, 3, 4, 5, 6, 7, 8, 9
3, 7, 8
8
8

I'm sure this can be shortened or written in a functional way.我相信这可以缩短或以功能方式编写。 I've tried using GroupBy, Distinct and Except, but couldn't figure it out that quickly.我试过使用 GroupBy、Distinct 和Except,但没能很快弄明白。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM