ConditionRacer
ConditionRacer

Reputation: 4498

Distinct with encapsulated equality

I have a collection of objects where I want to find distinct values based on several properties.

I could do this:

var distinct = myValues.GroupBy(p => new { A = p.P1, B = p.P2 });

But I want to encapsulate the equality sementics. Something like this:

public interface IKey<T>
{
    bool KeyEquals(T other);
}
public class MyClass : IKey<MyClass>
{
    public string P1 { get; set; }
    public string P2 { get; set; }
    public bool KeyEquals(MyClass other)
    {
        if(object.ReferenceEquals(this, other)
            return true;

        if(other == null)
            return false;

        return this.P1 == other.P1 && this.P2 == other.P2;
    }
}

Is there an O(N) way to get distinct values using my KeyEquals function?

Upvotes: 0

Views: 39

Answers (1)

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

If you can't change MyClass, you can implement an IEqualityComparer:

class MyClassComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass m1, MyClass m2)
    {
        return m1.KeyEquals(m2);
    }

    public int GetHashCode(MyClass m)
    {
       return (m.P1.GetHashCode() *23 ) + (m.P2.GetHashCode() * 17);
    } 
}

And pass it to GroupBy

var distinct = myValues.GroupBy(p => p, new MyClassComparer());

Upvotes: 1

Related Questions