使用linq将集合列表转换为分组集合列表

本文关键字:集合 列表 转换 linq 使用 | 更新日期: 2023-09-27 18:02:54

我需要根据一些属性分组创建新的列表,并使用相同的来生成MVC视图。

我有以下结构

class ItemLine
{
   string SomeProperty { get; set; } 
   string SomeProperty1 { get; set; } 
   string SomeProperty2 { get; set; } 
}
class Item
{
   IEnumerable<ItemLine> ItemLines { get; set; }
}
Class Order
{
   IEnumerable<Item> Items { get; set; }
}

Item类被接收为视图的模型。现在我要基于someProperty

创建多个IEnumerable

-Order-
       -Item-
              -ItemLine-
                         -someProperty = 123-
                         -someProperty1-
                         -someProperty2-
              -ItemLine-
                         -someProperty = 234-
                         -someProperty1-
                         -someProperty2-
              -ItemLine-
                         -someProperty = 345-
                         -someProperty1-
                         -someProperty2-
       -Item-
              -ItemLine-
                         -someProperty = 123-
                         -someProperty1-
                         -someProperty2-
              -ItemLine-
                         -someProperty = 456-
                         -someProperty1-
                         -someProperty2-
       -Item-
              -ItemLine-
                         -someProperty = 345-
                         -someProperty1-
                         -someProperty2-

Output needed is

    -Order-
           -Item-
                  -ItemLine-
                             -someProperty = 123-
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-
                             -someProperty = 123-
                             -someProperty1-
                             -someProperty2-    
                  -ItemLine-
                             -someProperty = null/blank-
                             -someProperty1-
                             -someProperty2-                                 
            -Item-               
                  -ItemLine-
                             -someProperty = 234-
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-             
                             -someProperty = null/blank-
                             -someProperty1-
                             -someProperty2-    
                  -ItemLine-             
                             -someProperty = null/blank-
                             -someProperty1-
                             -someProperty2-                                 
           -Item-
                  -ItemLine-
                             -someProperty = 345-
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-
                             -someProperty = 345-
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-             
                             -someProperty = null/blank-
                             -someProperty1-
                             -someProperty2-                                 
            -Item-               
                  -ItemLine-
                             -someProperty = 456-
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-
                             -someProperty = null/blank
                             -someProperty1-
                             -someProperty2-
                  -ItemLine-
                             -someProperty = null/blank
                             -someProperty1-
                             -someProperty2-

我已经尝试了一些事情,但无法实现这一点,请有人建议如何使用linq做到这一点。

谢谢! !

更新:我已经尝试以下,但它输出重复,我认为这不是最佳实践。

其中一个要求是,新的列表/集合必须具有与集合中任何项目的最大ItemLines数相同的ItemLines数,"额外"的ItemLines具有空、空或默认值。

foreach (var items in Model)
{
    foreach (var item in hm.Items)
    {
        var x = Model.SelectMany(u => u.Items).Where(u => u.ItemNo.Equals(item.ItemNo)).ToList();
    }
}

使用linq将集合列表转换为分组集合列表

这可能不是最好的方法,但由于您有需要所有Item s包含相同数量的ItemLine s的标准,这是我可以弄清楚的(并且很想看看其他人会如何做到这一点):

// Group the data out of your model organized by the SomeProperty value
// Order it by the number of items in the list so we know the first group will have the maximum number of values we'd need
var orderedGroups = Model.Items
    .SelectMany(itm => itm.ItemLines)
    .GroupBy(itm => itm.SomeProperty)
    .OrderByDescending(grp => grp.Count());
// Find out how many ItemLines you'd want to have in any 1 Item
var count = orderedGroups.First().Count();
// Create the output
var output = new Order() { 
                Items = orderedGroups
                .Select(grp => 
                    new Item() 
                    {
                        ItemLines = new ItemLine[count]
                        .Select((s,i) => grp.ElementAtOrDefault(i) ?? new ItemLine())
                    }
                )};

更新:

鉴于所作的评论,我假设您的Model只是Item的IEnumerable,而不是Order。在这种情况下,只需将第一行替换为:

// Group the data out of your model ordganized by the SomeProperty value
// Order it by the number of items in the list so we know the first group will have the maximum number of values we'd need
var orderedGroups = Model
    .SelectMany(itm => itm.ItemLines)
    .GroupBy(itm => itm.SomeProperty)
    .OrderByDescending(grp => grp.Count());

其余的都可以保持不变。