2016-08-17 8 views
2

流暢な(つまり「メソッド」)構文を使用してネストされたGroupBy LINQ式を書き込もうとしています。ネストされたGroupBy LINQの流暢構文の使用

ここで私のクラスとデータです:

class Person 
{ 
    public String ZipCode, Gender, Name; 
} 

private static List<Person> people = new List<Person> 
{ 
    new Person { ZipCode= "11111", Gender = "M", Name = "Tom" }, 
    new Person { ZipCode= "11111", Gender = "M", Name = "Bob" }, 
    new Person { ZipCode= "11111", Gender = "F", Name = "Nancy" }, 
    new Person { ZipCode= "11111", Gender = "F", Name = "Lisa" }, 
    new Person { ZipCode= "22222", Gender = "M", Name = "Dan" }, 
    new Person { ZipCode= "33333", Gender = "F", Name = "Mary" }, 
    new Person { ZipCode= "44444", Gender = "F", Name = "Joan" }, 
    new Person { ZipCode= "44444", Gender = "F", Name = "Jane" }, 
    new Person { ZipCode= "44444", Gender = "M", Name = "Bill" } 
}; 

私が達成したいと思ってる何がZipCodeGenderによって、その後ZipCodeによってグループ化されたオブジェクトです。オブジェクト型の面では、私はこれを探しています:

IEnumerable<IGrouping<string, IEnumerable<IGrouping<string, Person>>>> 

これは、その後、私はこのようなクエリ結果にアクセスできるようになる。ここでも

foreach(var byZip in mainQuery) { 
    Console.WriteLine(byZip.Key); // print the ZipCode 
    foreach(var byGender in byZip) { 
     Console.WriteLine(byGender.Key) // print the Gender 
     foreach (Person p in byGender) 
     Console.WriteLine(p.Name); 
    } 
} 

を、私は流暢な表記を使用していますよ。下記のジェフの答えに基づいて


、これは、クエリとアクセスです:

IEnumerable<IGrouping<string, IEnumerable<IGrouping<string, Person>>>> query = 
    people 
     .GroupBy(p => p.ZipCode) 
      .GroupBy(
       keySelector: g => g.Key, 
       elementSelector: g => g.GroupBy(p => p.Gender) 
      ); 


foreach (IGrouping<string, IEnumerable<IGrouping<string, Person>>> byZip in query) 
{ 
    Console.WriteLine(byZip.Key); // print the ZipCode 
    foreach (IEnumerable<IGrouping<string, Person>> byGender in byZip) 
    { 
     foreach (IGrouping<string, Person> t in byGender) 
     { 
      Console.WriteLine(t.Key); // print the Gender 
      foreach (Person y in t) 
       Console.WriteLine(y.Name); 
     } 

    } 
} 

答えて

6

、あなたはこのようにそれを書くことができますアクセスは実際のタイプと一致しません。

IEnumerable<IGrouping<string, IGrouping<string, Person>>> 

ので、クエリは次のようになります:あなたのアクセスパターンは、あなたのタイプが実際に可能になり

var query = 
    from p in people 
    group p by p.ZipCode into g 
    let gender = 
     from p in g 
     group p by p.Gender 
    from g2 in gender 
    group g2 by g.Key; 

そして変換...もう少し複雑です。

var query2 = people.GroupBy(p => p.ZipCode) 
    .SelectMany(g => 
     g.GroupBy(p => p.Gender).GroupBy(g2 => g.Key) 
    ); 
+0

直感的なスーパーカウンター(私はいつもパターンをやった直後に何があったのか忘れています)が働いています。クール:) –

0

var peopleGroupedByZipCode = people 
    .GroupBy(p => p.ZipCode) 
    .Select(group => new 
    { 
     ZipCode = group.Key, 
     PeopleGroupedByGender = group.GroupBy(p => p.Gender) 
    }); 

foreach (var resultsByZipCode in peopleGroupedByZipCode) 
{ 
    Console.WriteLine("ZipCode: " + resultsByZipCode.ZipCode); 
    foreach (var resultsByGender in resultsByZipCode.PeopleGroupedByGender) 
    { 
     Console.WriteLine(" Gender : " + resultsByGender.Key); 
     foreach (var resultWithinGenderGroup in resultsByGender) 
      Console.WriteLine(" " + resultWithinGenderGroup.Name); 

    } 
} 

は以下を書き出します:

ZipCode:11111

性別:M

トム

ボブ

性別:F

ナンシー

リサ

郵便番号:22222

性別:M

ダン

郵便番号:33333

性別:F

メアリー

郵便番号:44444

性別:F

ジョアン

ジェーン

性別:M

ビル

が希望そういったことですか?

(私はそれは、正確に人> > > > IEnumerableを< IGrouping <文字列、IEnumerableを< IGrouping <文字列ではないことを認識し、私はそれはあなたがその正確なタイプに興味を持っていたデータのより多くの形状であったことを考え出し)。

var query = 
    from p in people 
    group p by p.ZipCode into g 
    let gender = 
     from p in g 
     group p by p.Gender 
    group gender by g.Key; 

そして、これになるだろう「流暢」構文を使用して、それを変換:

var query2 = people.GroupBy(p => p.ZipCode) 
    .GroupBy(
     g => g.Key, 
     g => g.GroupBy(p => p.Gender) 
    ); 

しかし、あなたがしたい方法クエリ構文で

+0

これは機能しますが、私が言及した希望のタイプを得ることに固執していました。私はそれを理解できないことを苛立たせる。 –

関連する問題