【问题标题】:Using Linq to group a list of objects into a new grouped list of list of objects使用 Linq 将对象列表分组为新的对象列表分组列表
【发布时间】:2011-02-11 10:33:18
【问题描述】:

我不知道这在 Linq 中是否可行,但这里是……

我有一个对象:

public class User
{
  public int UserID { get; set; }
  public string UserName { get; set; }
  public int GroupID { get; set; }
}

我返回的列表可能如下所示:

List<User> userList = new List<User>();
userList.Add( new User { UserID = 1, UserName = "UserOne", GroupID = 1 } );
userList.Add( new User { UserID = 2, UserName = "UserTwo", GroupID = 1 } );
userList.Add( new User { UserID = 3, UserName = "UserThree", GroupID = 2 } );
userList.Add( new User { UserID = 4, UserName = "UserFour", GroupID = 1 } );
userList.Add( new User { UserID = 5, UserName = "UserFive", GroupID = 3 } );
userList.Add( new User { UserID = 6, UserName = "UserSix", GroupID = 3 } );

我希望能够在上述列表上运行 Linq 查询,按 GroupID 对所有用户进行分组。所以输出将是一个包含用户的用户列表列表(如果有意义的话?)。比如:

GroupedUserList
    UserList
        UserID = 1, UserName = "UserOne", GroupID = 1
        UserID = 2, UserName = "UserTwo", GroupID = 1
        UserID = 4, UserName = "UserFour", GroupID = 1
    UserList
        UserID = 3, UserName = "UserThree", GroupID = 2
    UserList
        UserID = 5, UserName = "UserFive", GroupID = 3
        UserID = 6, UserName = "UserSix", GroupID = 3

我尝试过使用 groupby linq 子句,但这似乎返回了一个键列表并且它没有正确分组:

var groupedCustomerList = userList.GroupBy( u => u.GroupID ).ToList();

【问题讨论】:

    标签: c# linq


    【解决方案1】:
    var groupedCustomerList = userList
        .GroupBy(u => u.GroupID)
        .Select(grp => grp.ToList())
        .ToList();
    

    【讨论】:

    • 非常好,正是我需要的。谢谢。这样做很糟糕。
    • 工作正常吗?因为我习惯了这种方式并没有奏效。 objModel.tblDonars.GroupBy(t => new { t.CreatedOn.Year, t.CreatedOn.Month, t.CreatedOn.Day }).Select(g => new { tblDonar = g.ToList() }).ToList( );这不起作用......你能帮忙......
    • 使用您的解决方案可以正常工作,但我有一个问题,假设组中最多 8 个值,我只想在每个组中只需要 6 次,所以如何做到这一点请告诉我。
    • 按GroupID分组后有没有办法分别列出UserNames和UserIDs?比如 - {"1", [1, 2, 4], ["UserOne", "UserTwo", "UserFour"]} 用于 groupID 1。
    • 当前代码不起作用,如果您尝试将其转换为以前的列表类型,则会导致错误。因为在 select 中返回一个列表会在列表中创建一个列表,这不是此处所需的输出。对于那些有问题的人,我可以建议: var groupedCustomerList = userList.GroupBy(u => u.GroupID).Select(grp => grp.First()).ToList();
    【解决方案2】:

    您的组声明按组 ID 分组。例如,如果你接着写:

    foreach (var group in groupedCustomerList)
    {
        Console.WriteLine("Group {0}", group.Key);
        foreach (var user in group)
        {
            Console.WriteLine("  {0}", user.UserName);
        }
    }
    

    应该可以正常工作。每个组一个键,但还包含一个IGrouping&lt;TKey, TElement&gt;,它是一个允许您遍历组成员的集合。正如 Lee 所提到的,如果您真的想要,您可以将每个组转换为一个列表,但如果您只是按照上面的代码对它们进行迭代,那么这样做并没有真正的好处。

    【讨论】:

      【解决方案3】:

      对于类型

      public class KeyValue
      {
          public string KeyCol { get; set; }
          public string ValueCol { get; set; }
      }
      

      收藏

      var wordList = new Model.DTO.KeyValue[] {
          new Model.DTO.KeyValue {KeyCol="key1", ValueCol="value1" },
          new Model.DTO.KeyValue {KeyCol="key2", ValueCol="value1" },
          new Model.DTO.KeyValue {KeyCol="key3", ValueCol="value2" },
          new Model.DTO.KeyValue {KeyCol="key4", ValueCol="value2" },
          new Model.DTO.KeyValue {KeyCol="key5", ValueCol="value3" },
          new Model.DTO.KeyValue {KeyCol="key6", ValueCol="value4" }
      };
      

      我们的 linq 查询如下所示

      var query =from m in wordList group m.KeyCol by m.ValueCol into g
      select new { Name = g.Key, KeyCols = g.ToList() };
      

      或用于数组而不是下面的列表

      var query =from m in wordList group m.KeyCol by m.ValueCol into g
      select new { Name = g.Key, KeyCols = g.ToList().ToArray<string>() };
      

      【讨论】:

        【解决方案4】:

        仍然是旧的,但李的回答没有给我 group.Key 结果。因此,我使用以下语句对列表进行分组并返回分组列表:

        public IOrderedEnumerable<IGrouping<string, User>> groupedCustomerList;
        
        groupedCustomerList =
                from User in userList
                group User by User.GroupID into newGroup
                orderby newGroup.Key
                select newGroup;
        

        现在每个组都有一个键,但还包含一个 IGrouping,它是一个允许您迭代组成员的集合。

        【讨论】:

        • 这回答了 your 的问题,而不是 OP 的问题。他们只想要一个列表列表。您的代码没有提供。
        • 我已经发布了这个解决方案,因为上面从@Lee 接受的答案在迭代时不起作用,因为它在迭代分组列表时提供了group.key 元素,例如在@JohnSkeet 的回答中显示。我提供的答案确实在迭代时提供了 group.key 元素。因此,它可能有助于其他人陷入所提供的答案不起作用的陷阱,如上所示。因此,这只是获取列表的另一种方法,它可以让 group.key 元素类似于已接受的答案。不明白你的主张@GertArnold。 (.net core 3.0)
        • 我认为整个问题是基于缺乏对IGrouping 的理解。这就是为什么 OP 在底部丢弃他们自己的正确代码,这与您的代码基本相同。这就是为什么他们接受一个能提供他们所要求的答案的原因。他们需要的是解释,JS充分提供了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-05
        • 1970-01-01
        • 1970-01-01
        • 2015-04-06
        • 1970-01-01
        • 2022-11-17
        相关资源
        最近更新 更多