示例结构是:
class Project {
public string Name { get; set; }
}
class TeamMember {
public string Email { get; set; }
public List<Project> Projects { get; set; }
}
是否有(简单)方法使用GroupBy为每个项目获取一个组,并将所有成员作为列表?
使用foreach(var group in members.GroupBy(m => m.Projects.First().Name))
时,显然只会按每个成员的第一个项目进行分组。但我希望所有可能的项目都包含所有成员的列表。
最简单的&#34;我能想到的解决方案是:(我还是通过foreach循环运行项目组)
var projects = members.SelectMany(m => m.Projects).Select(p => p.Name).Distinct().ToList();
foreach (var proj in projects)
{
var relevantMembers = members.Where(p => p.Projects.Select(pj => pj.Name).Contains(proj)).ToList();
...
}
答案 0 :(得分:6)
这是一种方法:
var result =
members.SelectMany(s => s.Projects.Select(x => (name: x.Name, obj: s)))
.GroupBy(x => x.name)
.ToDictionary(x => x.Key, x => x.Select(e => e.obj).ToList());
或者如果您没有使用C#7,那么您可以使用元组进行中间投影:
var result =
members.SelectMany(s => s.Projects.Select(x =>
new Tuple<string, TeamMember>(x.Name, s)))
.GroupBy(x => x.Item1)
.ToDictionary(x => x.Key, x => x.Select(e => e.Item2).ToList());
result
现在是Dictionary<string, List<TeamMember>>
类型。
或@RenéVogt建议您可以使用匿名类型进一步简化:
var result = members.SelectMany(s => s.Projects.Select(x => new { x.Name, s }))
.GroupBy(x => x.Name)
.ToDictionary(x => x.Key, x => x.Select(e => e.s).ToList());