列表项的组和计数列表

时间:2014-08-16 23:20:57

标签: c# linq

考虑以下因素:

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"}
        }
    }, 
};

由此我需要获得2个列表:一个包含特定组件在所有板中出现的次数,另一个列表包含在板上一起使用这些特定组件的次数。

我使用的第一个:

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

第二个是我的问题,结果应该是这样的:

[
 {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"}]} 
]

但是我很难开始这个。是否可以使用LINQ或者我应该使用foreach和手动比较?有关如何实现这一目标的任何提示吗?

1 个答案:

答案 0 :(得分:2)

您需要根据组件对数据列表进行分组。您需要实施一个IEqualityComparer,根据Id的{​​{1}}对您的列表进行比较:

Components

然后将其传递给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(); } }

GroupBy