GroupBy on list property→每个组中的对象

时间:2018-06-06 13:14:01

标签: c# linq

示例结构是:

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();
    ...
}

1 个答案:

答案 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());