我正在尝试使用流利(即“方法”)语法编写嵌套的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" }
};
我想要实现的是一个对象,按ZipCode
分组,然后Gender
分组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);
}
}
同样,我希望使用流利的符号。
根据Jeff的回答,这是查询和访问:
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);
}
}
}
答案 0 :(得分:7)
在查询语法中,您可以这样写:
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;
使用&#34;流利的&#34;转换它语法,这将成为这个:
var query2 = people.GroupBy(p => p.ZipCode)
.GroupBy(
g => g.Key,
g => g.GroupBy(p => p.Gender)
);
但是,您想要访问它的方式与实际类型不匹配。您的访问模式实际上是您的类型:
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)
);
答案 1 :(得分: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
南西
莉莎
ZipCode:22222
性别:M
丹
ZipCode:33333
性别:F
玛丽
ZipCode:44444
性别:F
琼
简
性别:M
比尔
这是你想要的那种吗?
(我意识到它不是一个IEnumerable&lt; IGrouping&lt; string,IEnumerable&lt; IGrouping&lt; string,Person&gt;&gt;&gt;&gt;但我认为它更像是你感兴趣的数据的形状精确型)。