C#:使用lambda对GroupBy的每个集合元素

时间:2016-08-12 12:37:37

标签: c# entity-framework linq lambda grouping

我有一个Component的集合,这些集合包含Pax的集合:

public class Component
{
    public IEnumerable<Pax> Paxes { get; set; }  
}

public class Pax
{
    public int Number { get; set; }  
    public int Room { get; set; }
}

我想将乘客列表中的Component集合(IEnumerable<Component>)分组。

var groups = components.GroupBy(c => c.Paxes);

当然,不期望这些团体。在组件中重复的Paxes没有相同的对象引用,所以我必须在组表达式中比较它们的属性,这就是我被卡住的地方。

2 个答案:

答案 0 :(得分:4)

您必须为其实施IEqualityComparer

List<Component> components = new List<Component>();
var result = components.GroupBy(c => c.Paxes, new PaxesComparer());

public class PaxesComparer : IEqualityComparer<IEnumerable<Pax>>
{
    public bool Equals(IEnumerable<Pax> x, IEnumerable<Pax> y)
    {
        throw new NotImplementedException();
    }

    public int GetHashCode(IEnumerable<Pax> obj)
    {
        throw new NotImplementedException();
    }
}
  1. 实施Equals - 您可以查看this question以检查收藏是否相同。
  2. 您可能还想覆盖Equals课程的GetHashCodePax
  3. 确保您实施GetHashcode - 因为如果哈希值不同则将不会调用 - Kirill的评论如下

答案 1 :(得分:2)

您可以使用此通用集合相等比较器。

public class CollectionEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public int GetHashCode(IEnumerable<T> obj)
    {
        unchecked
        {
            return obj.Aggregate(17, (current, item) => current * 31 + item.GetHashCode());
        }
    }

    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        return x.SequenceEqual(y);
    }
}

然后

var q = components.GroupBy(c => c.Paxes, new CollectionEqualityComparer<Pax>()));

这当然要求Pax对象覆盖EqualsGetHashCode