4

I have a collection of Component and these collections have a collection of Pax:

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

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

I would like to group my Component collection (which is an IEnumerable<Component>) by the list of passenger.

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

Of course, those groups are not expected. Paxes repeated in components have not the same object reference, so I have to compare their properties in the group expression and this is where I'm stuck.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
J-R Choiniere
  • 634
  • 5
  • 19

2 Answers2

4

You must implement an IEqualityComparer for it:

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. For implementation of Equals - You can check this question to check that the collections are identical.
  2. You'd probably also want to override Equals and GetHashCode of Pax class.
  3. Make sure you implement GetHashcode - cause if hashes are different equals will not be called - Kirill's comment below
Community
  • 1
  • 1
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
2

You can use this generic collection equality comparer.

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

And then

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

This of course requires the Pax object to override Equals and GetHashCode.

Magnus
  • 45,362
  • 8
  • 80
  • 118