Come ottenere valori da IGrouping


211

Ho una domanda IGroupinge il Select()metodo.

Diciamo che ho un IEnumerable<IGrouping<int, smth>>in questo modo:

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

dov'è lista List<smth>.

E ora ho bisogno di passare i valori di ciascuno IGroupinga un altro elenco in qualche modo:

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

Qualcuno può suggerire come ottenere i valori ( List<smth>) da un IGrouping<int, smth>in un tale contesto?


L'ID è di solito un campo di identità che dovrebbe essere univoco, il che renderebbe inutile il raggruppamento in base a esso, se invece stai solo cercando di rimuovere i dati duplicati prova Distinct (). se fosse list.GroupBy (x => x.SubID), allora avrebbe senso usare il raggruppamento ma in quel caso probabilmente vorrai mantenere il raggruppamento e foreach (var grp in gruppi) {grp.ToList () ; } lo farebbe
MikeT il

Risposte:


277

Dal momento che IGrouping<TKey, TElement>implementa IEnumerable<TElement>, è possibile utilizzare SelectManyper riunire tutti IEnumerablesin un tutt'uno IEnumerable:

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
Non è lo stesso di un normale "orderBy"? Elenco <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ,

@MorgoZ, la domanda è di prendere il groupse tornare a una lista piatta.
Matt Smith,

3
@MorgoZ, OrderBy(x => x.id)li ordinerà in ordine crescente per ID. In contrasto con questo .GroupBy(x => x.id).SelectMany(group => group), che li ordinerà in base alla prima apparizione di ID. Se gli ID originali sono nell'ordine: [1,3,2,2,2,3,0], quindi raggruppandoli e appiattendoli in un elenco inserirai gli ID nel nuovo ordine: [1,3,3, 2,2,2,0].
Pi Fisher,

2
Non funziona per me .. dice che il tipo non può essere dedotto dall'uso
Revious

3
il tipo non può essere dedotto dall'uso
Leo Gurdian,

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

Per prima cosa devi selezionare il gruppo desiderato. Quindi è possibile utilizzare il ToListmetodo di sul gruppo. La IGroupingè una IEnumerabledei valori.


17

Versione più chiara delle risposte sopra:

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;
    }
}

Non penso proprio, almeno per ora.
snr

15

Dalla definizione di IGrouping:

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

puoi semplicemente scorrere attraverso elementi come questo:

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

1
che scorre attraverso non raggruppa gli elementi nel gruppo
MikeT

1
Oh mio errore, quindi: 'foreach (smth p in group.SelectMany (sth => sth))'
user1275513
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.