以下linq查询根据他们的职业对城市中的人进行分组。
然而,我能够让它发挥作用的唯一方法就是对城市进行硬编码。
每个人都有一个城市。如何修改以下查询,使其按查询中返回的所有不同城市进行分组?
profession = people
.GroupBy(p => p.Profession).
Select(group =>
new
{
name = group.Key,
data =
new List<int>()
{
group.Count(p => p.City == "Adelaide"),
group.Count(p => p.City == "Brisbane"),
group.Count(p => p.City == "Canberra"),
group.Count(p => p.City == "Darwin"),
group.Count(p => p.City == "Melbourne"),
group.Count(p => p.City == "Perth"),
group.Count(p => p.City == "Sydney"),
},
})
即如果我的数据集是:
Person {id:1, city: "Paris" }
Person {id:2, city: "Paris" }
Person {id:3, city: "London" }
然后生成的查询将是:
profession = people
.GroupBy(p => p.Profession).
Select(group =>
new
{
name = group.Key,
data =
new List<int>()
{
group.Count(p => p.City == "Paris"),
group.Count(p => p.City == "London"),
},
})
答案 0 :(得分:0)
这会产生与硬编码列表相同的输出,但我不确定它是否符合您的要求(提示:在这方面给我们预期的输出会有很大帮助)。
它只是创建一个不同的城市列表,然后构建一个谓词delegate,用于计算每个城市的出现次数,并将该谓词添加到列表中。执行实际分组时,将使用分组结果调用列表中的每个谓词。
符号Func<IGrouping<string, Person>, int>
简单地说&#34;这是一个委托,它接受IGrouping<string, Person>
个对象(调用GroupBy
的结果)并返回int
(调用Count
)&#34;。
class Program
{
static void Main(string[] args)
{
var people = new List<Person>()
{
new Person(1, "Paris", "carpenter"),
new Person(2, "Paris", "bricklayer"),
new Person(3, "London", "video game critic"),
};
var distinctCities = people.Select(p => p.City).Distinct();
var groupPredicates = new List<Func<IGrouping<string, Person>, int>>();
foreach (var city in distinctCities)
{
groupPredicates.Add(g => g.Count(p => p.City == city));
}
var professions = people
.GroupBy(p => p.Profession)
.Select(g =>
new
{
name = g.Key,
data = groupPredicates.Select(gp => gp(g)),
});
foreach (var profession in professions)
{
Console.WriteLine(profession.name + " =>");
foreach (var count in profession.data)
{
Console.WriteLine(" " + count);
}
}
Console.ReadKey(true);
}
}
struct Person
{
public int Id { get; set; }
public string City { get; set; }
public string Profession { get; set; }
public Person(int id, string city, string profession)
{
Id = id;
City = city;
Profession = profession;
}
}