Cómo obtener valores de IGrouping


211

Tengo una pregunta sobre IGroupingy el Select()método.

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

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

donde listesta a List<smth>.

Y ahora necesito pasar los valores de cada uno IGroupinga otra lista de alguna manera:

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

¿Alguien puede sugerir cómo obtener los valores ( List<smth>) de un IGrouping<int, smth>en ese contexto?


El ID generalmente es un campo de identidad que debería ser único, lo que haría que agruparlo fuera inútil, si solo está tratando de eliminar datos duplicados, intente Distinct () 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

Respuestas:


277

Desde IGrouping<TKey, TElement>implementos IEnumerable<TElement>, puede usar SelectManypara poner todo de IEnumerablesnuevo en uno IEnumerabletodo junto:

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

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

@MorgoZ, la pregunta es acerca de tomar el groupsy volver a una lista plana.
Matt Smith

3
@MorgoZ, OrderBy(x => x.id)los ordenará en orden ascendente por ID. Compare esto con .GroupBy(x => x.id).SelectMany(group => group), que los ordenará por orden de primera aparición de ID. Si las ID originales están en el orden: [1,3,2,2,2,3,0], al agruparlas y luego aplanarlas en una lista colocará las ID en el nuevo orden: [1,3,3, 2,2,2,0].
Pi Fisher

2
No funciona para mí ... dice que el uso no puede inferir el tipo
Anterior

3
tipo no puede inferirse por el uso
Leo Gurdian

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

Primero debe seleccionar el grupo deseado. Entonces puede usar el ToListmétodo de en el grupo. El IGroupinges uno IEnumerablede los valores.


17

Versión más aclarada 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;
    }
}

No lo creo, al menos por ahora.
snr

15

De la definición de IGrouping:

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

puedes iterar a través de elementos como este:

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

1
que itera a través de él no agrupa los elementos del grupo
MikeT

1
Oh, mi error, entonces: 'foreach (smth p en grupos.SelectMany (sth => sth))'
usuario1275513
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.