合并两个IGrouping集

时间:2014-03-28 12:49:24

标签: c# .net linq

假设我有三个用户,我想按国家/地区分组。我会这样做:

var users = new[]
{
    new User { Name = "Phil", Country = "UK" },
    new User { Name = "John", Country = "UK" },
    new User { Name = "Mike", Country = "USA" }
};

List<IGrouping<string, User>> groupedUsers
    = users.GroupBy(user => user.Country).ToList();

现在假设我的程序稍后会再增加三个用户,所以我也将它们分组:

var moreUsers = new[]
{
    new User { Name = "Phoebe", Country = "AUS" },
    new User { Name = "Joan", Country = "UK" },
    new User { Name = "Mindy", Country = "USA" }
};

List<IGrouping<string, User>> moreGroupedUsers
    = moreUsers.GroupBy(user => user.Country).ToList();

我现在有两个单独的分组,groupedUsersmoreGroupedUsers。如何在保持分组有效的同时将它们合并为一个?

2 个答案:

答案 0 :(得分:11)

由于IGrouping<,> API不提供变异接口,您需要:

  • 简单地连接并重新分组
  • 使用变异容器,可以添加Dictionary<string, List<User>>

第一听起来更简单。它可能是:

var groupedUsers = groupedUsers.SelectMany(grp => grp)
        .Concat(moreUsers)
        .GroupBy(x => x.Country).ToList();

或:

var groupedUsers = users.Concat(moreUsers)
        .GroupBy(x => x.Country).ToList();

(如果您仍有users可用)

后者可以通过以下方式完成:

var mutable = users.GroupBy(user => user.Country).ToDictionary(
        grp => grp.Key, grp => grp.ToList());

然后(追加):

foreach(var user in moreUsers) {
    List<User> list;
    if(!mutable.TryGetValue(user.Country, out list)) {
        mutable.Add(user.Country, list = new List<User>());
    }
    list.Add(user);
}

答案 1 :(得分:0)

我知道它有点晚了,但这可能有助于其他可能想要避免使用Dictionary课程的人。这个&#34;解决方案&#34;可能会导致大型集合和重复执行的性能问题。

您只需要使用users方法展平IEnumerable.SelectMany组合集,然后使用Enumerable.Concat方法将新元素连接到展平集合,最后使用{{{{}}重新组合元素1}}再次。

示例:

IEnumerable.GroupBy