简体   繁体   English

分组和计数清单项目清单

[英]Group and count list of list items

Considering the following: 考虑以下内容:

public class Board
{
    public List<Component> Components { get; set; }
}

public class Component
{
    public int Id { get; set; }
    public string Name { get; set; }
}



var data = new[]{   

    new Board{ 
        Components = new List<Component> {
            new Component{Id = 1, Name= "Item 1"},
            new Component{Id = 2, Name= "Item 2"}
        }
    }, 
    new Board{ 
        Components = new List<Component> {
            new Component{Id = 1, Name= "Item 1"},
            new Component{Id = 3, Name= "Item 3"}
        }
    },      
    new Board{ 
        Components = new List<Component> {
            new Component{Id = 2, Name= "Item 2"},
            new Component{Id = 1, Name= "Item 1"}
        }
    }, 
    new Board{ 
        Components = new List<Component> {
            new Component{Id = 1, Name= "Item 1"},
            new Component{Id = 2, Name= "Item 2"},
            new Component{Id = 3, Name= "Item 3"}
        }
    }, 
};

From this I need to get 2 lists: one containing how many times a specific component appear in all Boards and other list containing how many times those specific Component have been used together on a Board. 由此,我需要获得2个列表:一个包含某个特定组件在所有Board中出现的次数,另一个包含该特定组件在一个Board中一起使用了多少次的列表。

The first one I get using this: 我使用的第一个:

var componentsCount = data.SelectMany(x => x.Components)
               .GroupBy(x => x.Id)
               .Select(x => new { Item = x.First(), Count = x.Count() });

The second one is my problem, the result should be something like this: 第二个是我的问题,结果应该是这样的:

[
 {Count = 2, Components = [{ Id = 1, Name = "Item 1"}, { Id = 2, Name = "Item 2"}]}
 {Count = 1, Components = [{ Id = 1, Name = "Item 1"}, { Id = 3, Name = "Item 3"}]}
 {Count = 1, Components = [{ Id = 1, Name = "Item 1"}, { Id = 2, Name = "Item 2"}, { Id = 3, Name = "Item 3"}]} 
]

But I am having a hard time even starting this. 但是即使开始,我也很难。 Is it possible with LINQ or should I resort to foreachs and manual comparison? LINQ是否有可能,还是我应该求助于foreach和手动比较? Any hint on how to achieve this? 关于如何实现这一点的任何提示?

You need to group your data list based on the components. 您需要根据组件对数据列表进行分组。 You need to implement a IEqualityComparer which compares your lists based on the Id of the Components : 您需要实现IEqualityComparer ,该IEqualityComparer会根据ComponentsId比较您的列表:

class ComponentListComparer : IEqualityComparer<List<Component>>
{

    public bool Equals(List<Component> x, List<Component> y)
    {
        return x.Select(c => c.Id)
            .OrderBy(c => c)
            .SequenceEqual(y.Select(c => c.Id).OrderBy(c => c));
    }

    public int GetHashCode(List<Component> obj)
    {
        return obj.Select(x => x.Id.GetHashCode() * 23).Sum();
    }

}

Then pass it to GroupBy : 然后将其传递给GroupBy

 var result = data.GroupBy(x => x.Components, new ComponentListComparer())
            .Select(g => new {Count = g.Count(), Components = g.Key})
            .ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM