LINQ 组由子项的子项

本文关键字:LINQ | 更新日期: 2023-09-27 18:32:29

我不确定这个问题是否重复,因为这是我努力寻找的东西,因为基本上我不知道功能名称是什么。因此,如果是这样的话,我深表歉意。

举个例子,一个团队有人员,而这个人有几个电话号码,我想按号码分组,并仍然保留与团队相关的所有信息。所以基本上使属性编号成为我的分组的键。

public class PhoneNumber
{
   public string Number { get; set; }
}
public class Person
{
  public List<PhoneNumber> PhoneNumbers { get; set; }
}
public class Team
{
  public List<Person> Persons{ get; set; }
}
IEnumerable<Team> teams = new List<Team>();

所以我想做一些类似的事情:

Team.Persons.GroupBy(i=> i.PhoneNumbers.Number)

显然我不能,因为电话号码是一个列表

最终结果应该是这样的

  • 编号1234 -> 团队 1, 团队 2
  • 编号5678 -> 团队 1、团队 2、团队 3

其中,NumberX 是分组键,TeamX 包含与具有该电话号码的成员的团队关联的信息。

可能是我的方法在这个例子上完全不合适,所以任何反馈将不胜感激。

LINQ 组由子项的子项

你基本上需要把结果展平,这样你就有了球队/号码对,然后你可以按数字分组。所以例如:

// IEnumerable<IGrouping<string, Team>>
var grouped = from team in teams
              from person in team.Persons
              from number in person.PhoneNumbers
              group team by number.Number;

您可能还需要考虑创建Lookup而不是分组:

// ILookup<string, Team>
var lookup = (from team in teams
              from person in team.Persons
              from number in person.PhoneNumbers
              select new { team, number }).ToLookup(p => p.number.Number,
                                                    p => p.team);

通过查找,您可以执行以下操作:

var number = "...";
foreach (var team in lookup[number])
{
    ...
}

。如果您要求使用未知电话号码的团队,它将帮助返回一个空序列。

其中一种方法是选择所有电话号码及其相关团队,然后您可以进行分组,如下所示:

var teamsGrouppedByPhoneNumbers = (from t in Teams
from p in t.Persons
from pn in p.PhoneNumbers
select new { Team = t, PhoneNumber = pn })
.GroupBy(x => x.PhoneNumber.Number)
.ToList();