2012-05-28 14 views
6

これは簡単な作業ですが、LINQでこれを行う方法を理解できません。私がこれまでに見つけた唯一の情報は、ラウンドロビントーナメントの形式に関するものですが、これは私の後ではありません。私は間違っているかもしれない。以下のリストを考える:それは「ラウンドロビン」の順番で出てくるようにLINQ order by "round robin"

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

はちょうど私がこれを書いていた間、2つの答えがポップアップすることを見ました。まあ、別の方法です:

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