2012-05-28 15 views
6

Wygląda na to, że powinno to być łatwe zadanie, ale nie mogę wymyślić, jak to zrobić z LINQ. Jedyne informacje, jakie udało mi się znaleźć do tej pory, dotyczą formatu turnieju round robin, który nie jest tym, na co czekam. Mogę szukać źle. Biorąc pod uwagę następującą listę:Zamówienie LINQ przez "round robin"

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

Jak mogę rozwiązać ten (najlepiej przy użyciu LINQ) tak, że wychodzi w „round robin” porządku, to znaczy wybrać każdą wyjątkową pozycję kiedyś powtórzeń. Więc powyższa lista nie wyjdzie tak (To nie jest ważne, jeśli chodzi w porządku alfabetycznym, choć ta lista nie):

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

wiem, że mogę to zrobić przez iteracji nad nim w bolesny sposób, że po prostu liczył na coś łatwiejszego. Czy ktoś ma wgląd w to, jak to zrobić? Z góry dziękuję!

+0

Czy możesz wyjaśnić, co dokładnie rozumiesz przez sortowanie "round-robin"? – mattytommo

+0

Ma na myśli sortowanie "round-robin" http://pl.wikipedia.org/wiki/Round-robin – Likurg

Odpowiedz

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

powinien nauczyć się poprawnie kopać. zaakceptuj to, działa to. – Alex

+1

ładne podejście, lubię to! – HugoRune

+0

Jesteście niesamowici. Działa idealnie. Dziękuję Ci! Wszystko, co musiałem zmienić, to GroupBy dla mojego projektu, aby pogrupować według rzeczywistej unikalnej rzeczy, na której mi zależało, a reszta została dosłownie skopiować i wkleić. Dzięki jeszcze raz! – Eric

0

Zrobiłem to raz, wykopane kod:

//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

właśnie zobaczyłem, że dwie odpowiedzi pojawiło się podczas pisania tego; no cóż, tutaj jest inny sposób:

Powiązane problemy