使用linq将收集列表转换为分组的收集列表 [英] Collection list to grouped collection list using linq

查看:82
本文介绍了使用linq将收集列表转换为分组的收集列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要基于对某些属性的分组来创建新列表,并使用它们来生成MVC视图.

I need to create new lists based on grouping on some property and use the same to generate MVC View.

我有以下结构

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

Item class is received as Model to the view. Now I want to create multiple IEnumerable based on someProperty

例如

-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做到这一点.

I have tried few things but am not able to achieve this can some one please suggest how to do this using linq.

谢谢!

更新:我尝试了以下操作,但是它输出重复项,我认为这不是最佳做法.

Update : I have tried following but it outputs duplicates and I think its not best practice.

其中一项要求是,新列表/集合必须具有与集合中任何项目中最大项目行数相同的项目行数,并且额外"项目行的属性应为null,空白或默认值.

One of the requirements is that the new lists/collections must have same number of ItemLines as the maximum number of ItemLines in any Item in the collection, with the "extra" ItemLines having null, blank or default values for their properties.

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();
    }
}

推荐答案

这可能不是最好的方法,但是由于您必须满足所有Item包含相同数量的ItemLine s,这就是我能弄清楚的(很想看看别人会怎么做):

This is probably not the nicest way to do this, but since you have the criteria of needing to have all the Items containing the same number of ItemLines, this is what I could figure out (and would love to see how someone else would do this):

// 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.在这种情况下,只需将第一行替换为:

Given the comment made, I'm assuming your Model is simply an IEnumerable of Item rather than an Order. That being the case, simply replace the first line to:

// 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());

其余的都可以保持不变.

All the rest can stay the same.

希望这能解决问题.

这篇关于使用linq将收集列表转换为分组的收集列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆