2012-05-28 16 views
6

Parece que esto debería ser una tarea fácil, pero no puedo encontrar la manera de hacerlo con LINQ. La única información que he podido encontrar hasta ahora es sobre el formato del torneo round robin, que no es lo que busco. Es posible que esté buscando mal. Dada la siguiente lista:LINQ orden por "round robin"

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

¿Cómo puedo solucionar esto (preferiblemente usando LINQ) para que salga con el fin de "round robin", es decir, seleccionar cada elemento único una vez antes de repeticiones. Por lo que la lista anterior saldría como esto (No es importante si sale en orden alfabético, a pesar de que esta lista):

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

Sé que puedo hacer esto mediante la iteración sobre la manera difícil, yo solo esperaba algo más fácil. ¿Alguien tiene alguna idea de cómo hacer esto? ¡Gracias por adelantado!

+0

¿Puede explicar exactamente qué quiere decir con la clasificación "round-robin"? – mattytommo

+0

Se refiere a la clasificación "round-robin" http://en.wikipedia.org/wiki/Round-robin – Likurg

Respuesta

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

debería aprender a copiar la pasta correctamente. acepta esto, esto funciona. – Alex

+1

buen enfoque, me gusta! – HugoRune

+0

Usted señor es increíble. Funciona perfectamente ¡Gracias! Todo lo que necesitaba cambiar era GroupBy para mi proyecto para agruparlo por el elemento único real que me importaba, el resto era literalmente copiar y pegar. ¡Gracias de nuevo! – Eric

0

Lo hice una vez, desenterrado el código:

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

acabamos de ver que dos respuestas aparecieron mientras estaba escribiendo esto; Bueno, aquí hay otra forma:

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