LINQ命令“循环”

时间:2012-05-28 11:05:35

标签: linq round-robin

似乎这应该是一项简单的任务,但我无法弄清楚如何使用LINQ执行此操作。到目前为止我能找到的唯一信息是关于循环比赛的格式,这不是我想要的。我可能错了。鉴于以下列表:

var items [] { "apple", "banana", "banana", "candy", "banana", "fruit", "apple" };

如何对此进行排序(最好使用linq),使其以“循环”顺序排出,即在重复之前选择每个唯一项目一次。所以上面的列表会像这样出现(如果它按字母顺序排列并不重要,即使这个列表确实如此):

var sorted [] { "apple", "banana", "candy", "fruit", "apple", "banana", "banana" };

我知道我可以通过艰难的方式迭代它来做到这一点,我只是希望更容易。有没有人有任何见解如何做到这一点?提前谢谢!

3 个答案:

答案 0 :(得分:8)

var sorted = items.GroupBy(s => s)
    .SelectMany(grp => grp.Select((str, idx) => new { Index = idx, Value = str }))
    .OrderBy(v => v.Index).ThenBy(v => v.Value)
    .Select(v => v.Value)
    .ToArray();

答案 1 :(得分:0)

我做了一次,挖出了代码:

//Originially written for lists, all you need is prepend a .ToList() where needed to apply this to an array
List<string> src = new List<string> { "string1", "string2" }; //source
List<string> dst = new List<string>();

dst.AddRange(src.Distinct());
dst.ForEach(d => src.RemoveAt(src.FindIndex(i => i.Equals(d)))); //remove the first occurrence of each distinct element
dst.AddRange(src);

答案 2 :(得分:0)

我写这篇文章的时候刚刚看到两个答案突然出现了;哦,这是另一种方式:

var items [] { "apple", "banana", "banana", "candy", "banana", "fruit", "apple" };

var uniqueItems = items.Distinct().OrderBy(item => item); // alphabetical orderBy is optional

var duplicateItems = items
                     .GroupBy(item => item)
                     .SelectMany(group => group.Skip(1))
                     .OrderBy(item => item); // alphabetical orderBy is optional;

var sorted = uniqueItems.Append( duplicateItems ).ToArray();