IGroupingから値を取得する方法


211

IGroupingとそのSelect()方法について質問があります。

私がIEnumerable<IGrouping<int, smth>>このように持っているとしましょう:

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

どこlistですList<smth>

そして今、私はそれぞれの値をIGrouping何らかの方法で別のリストに渡す必要があります:

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

そのようなコンテキストでList<smth>から値()を取得する方法を誰かが提案できIGrouping<int, smth>ますか?


IDは通常、一意である必要がある識別フィールドです。重複データを削除しようとするだけでDistinct()を試してみると、IDによるグループ化が役に立たなくなります。list.GroupBy(x => x.SubID)の場合、グループ化を使用することは理にかなっていますが、その場合はグループ化を維持し、foreach(var grp in groups){grp.ToList() ; }はそれを行います
MikeT 2013年

回答:


277

はをIGrouping<TKey, TElement>実装しているのでIEnumerable<TElement>、を使用SelectManyして、すべてIEnumerablesを1つにまとめることができます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
それは通常の「orderBy」と同じではありませんか?List <smth> newList = list .OrderBy(x => x.id).ToList();
MorgoZ

@MorgoZ、問題はを取り、groupsフラットなリストに戻すことです。
マット・スミス

3
@MorgoZは、OrderBy(x => x.id)IDで昇順に並べ替えます。これをと比較すると.GroupBy(x => x.id).SelectMany(group => group)、IDの最初の出現順にソートされます。元のIDの順序が[1,3,2,2,2,3,0]の場合、それらをグループ化してから1つのリストにフラット化すると、IDが新しい順序に配置されます:[1,3,3、 2,2,2,0]。
Pi Fisher

2
それは私のために動作しません..それは型が使用法によって推論されることができないと言います
以前の

3
タイプは使用法から推測できません
Leo Gurdian '14 / 06/14

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

まず、目的のグループを選択する必要があります。その後ToList、グループのメソッドを使用できます。IGroupingあるIEnumerable値の。


17

上記の回答のより明確なバージョン:

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

少なくとも今のところはそうは思いません。
snr

15

IGroupingの定義から:

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

次のような要素を繰り返すだけです。

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

1
グループ内のアイテムではなく、グループ全体を反復処理します
MikeT 2013年

1
ああ私の間違い、それから: 'foreach(smth p in groups.SelectMany(sth =>
sth
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.