2011-12-15 22 views
132

Tengo una pregunta sobre el método IGrouping y Select().Cómo obtener valores de IGrouping

Digamos que tengo IEnumerable<IGrouping<int, smth>> de esta manera:

var groups = list.GroupBy(x => x.ID); 

donde lista es un List<smth>.

Y ahora tengo que pasar valores de cada IGrouping a otra lista de alguna manera .:

foreach (var v in structure) 
{ 
    v.ListOfSmth = groups.Select(...); // <- ??? 
} 

¿Puede alguien sugerir cómo conseguir valores (List<smth>) de IGrouping<int, smth> en este contexto?

+0

ID suele ser un campo de identidad que debe ser único, lo que haría agrupación por inútil, si simplemente se trata de eliminar los datos duplicados tratan distintos() en su lugar. si fuera list.GroupBy (x => x.SubID), entonces tendría sentido usar la agrupación, pero en ese caso lo más probable es que desee mantener la agrupación y foreach (var grp en grupos) {grp.ToList() ; } haría eso – MikeT

Respuesta

193

Desde IGrouping<TKey, TElement> implementa IEnumerable<TElement>, puede utilizar SelectMany poner toda la IEnumerables de nuevo en una IEnumerable todos juntos:

List<smth> list = new List<smth>(); 
IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.id); 
IEnumerable<smth> smths = groups.SelectMany(group => group); 
List<smth> newList = smths.ToList(); 
+2

¿No es lo mismo que un "orden" normal? List newList = list .OrderBy (x => x.id) .ToList(); – MorgoZ

+0

@MorgoZ, la pregunta es acerca de tomar los 'grupos' y volver a una lista plana. –

+1

@MorgoZ, 'OrderBy (x => x.id)' ordenará en orden ascendente por ID. Contraste esto con '.GroupBy (x => x.id) .SelectMany (group => group)', que los ordenará por orden de aparición de ID por primera vez. Si los ID originales están en el orden: [1,3,2,2,2,3,0], agrupándolos y luego aplanándolos en una lista los colocarán en el nuevo orden: [1,3, 3,2,2,2,0]. –

24
foreach (var v in structure) 
{  
    var group = groups.Single(g => g.Key == v. ???); 
    v.ListOfSmth = group.ToList(); 
} 

En primer lugar es necesario seleccionar el grupo deseado. Luego puede usar el método ToList en el grupo. El IGrouping es un IEnumerable de los valores.

7

Desde definición de IGrouping:

IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable 

que sólo puede iterar a través de elementos de esta manera:

IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.ID) 
foreach(IEnumerable<smth> element in groups) 
{ 
//do something 
} 
+0

que itera a través de él no agrupa los elementos en el grupo – MikeT

+0

Oh mi error, entonces: 'foreach (smth p en groups.SelectMany (sth => sth)) ' – user1275513

8

versión Más aclarado de las respuestas anteriores:

IEnumerable<IGrouping<int, ClassA>> groups = list.GroupBy(x => x.PropertyIntOfClassA); 

foreach (var groupingByClassA in groups) 
{ 
    int propertyIntOfClassA = groupingByClassA.Key; 

    //iterating through values 
    foreach (var classA in groupingByClassA) 
    { 
     int key = classA.PropertyIntOfClassA; 
    } 
} 
Cuestiones relacionadas