使用 Linq 将对象列表分组为新的对象列表分组列表

Posted

技术标签:

【中文标题】使用 Linq 将对象列表分组为新的对象列表分组列表【英文标题】:Using Linq to group a list of objects into a new grouped list of list of objects 【发布时间】: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();

【问题讨论】:

【参考方案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充分提供了。

以上是关于使用 Linq 将对象列表分组为新的对象列表分组列表的主要内容,如果未能解决你的问题,请参考以下文章

Linq to sql,聚合列,按日期分组到列表视图

在python中以某列为分组对象还能对某列进行依次排序吗

Spring数据存储库按列分组,包含其他列的对象列表

LINQ分组[重复]

Linq:根据另一个列表分组和求和

如何输出分组对象中指定列中所有值的列表