2012-05-28 73 views
6

似乎这样应该是一件容易的事,但我不知道如何用LINQ做到这一点。目前我唯一能找到的信息是关于循环赛的格式,这不是我所追求的。我可能在搜索错误。鉴于以下列表:LINQ顺序通过“循环”

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

我怎样才能解决这(最好使用LINQ),因此它在“循环”为了出来,也就是重复前一次选择每一个独特的项目。所以上面的列表会出来这样的(如果按字母顺序排列出来这不是重要的,尽管这个名单确实):

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

我知道我可以通过遍历它的硬盘的方式做到这一点,我只是希望更容易一些。有没有人有任何见解如何做到这一点?提前致谢!

+0

你能解释一下你的意思是什么“循环”排序? – mattytommo

+0

他的意思是“循环”排序http://en.wikipedia.org/wiki/Round-robin – Likurg

回答

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(); 
+0

应该学会正确地复制粘贴。接受这个,这个工作。 – Alex

+1

不错的做法,我喜欢它! – HugoRune

+0

你先生真棒。它完美的作品。谢谢! 我需要改变的是我的项目的GroupBy,以便按照我关心的实际独特项目进行分组,其余的完全是复制粘贴。再次感谢! – Eric

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); 
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();