Linq query question: Distinct based on object's property

1.4k views Asked by At

I am aggregating multiple List's into one List and would like to make it distinct based on one of the properties of Foo (Foo.Prop1).. I do not have access to modify Foo's Equality comparer.

Dictionary<string, List<Foo>> fooDictionary = new Dictionary<string, List<Foo>>();
List<Foo> foovals = (from e in fooDictionary
                     where e.Key == "foo1" || e.Key == "foo2" || e.Key == "foo3"
                     select e.Value).SelectMany(f => f).ToList();

the only thing missing here is the .Distinct() at the end, to make Foo's unique, however, in my case, i can't modify anything about Foo, so simply calling Distinct() will not work.

Is there a way to modify this query to return items Distinct based on Foo.Prop1 ?

3

There are 3 answers

1
Jon Skeet On BEST ANSWER

You could use the DistinctBy method in MoreLINQ:

var query = fooVals.DistinctBy(foo => foo.Property1);
18
codekaizen On

You can pass a custom equality comparer to Distinct():

.SelectMany().Distinct(new FooEqualityComparer());

In a new file, "FooEqualityComparer.cs":

public class FooEqualityComparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        return Equals(x.Prop1, y.Prop1);
    }

    public int GetHashCode(Foo x)
    {
        return x.Prop1.GetHashCode();
    }
}
2
LukeH On
var tempKeys = new HashSet<int>();    // change int to the actual type of Prop1

List<Foo> foovals = (from e in fooDictionary
                     where e.Key == "foo1" || e.Key == "foo2" || e.Key == "foo3"
                     select e.Value).SelectMany(f => f)
                                    .Where(f => tempKeys.Add(f.Prop1))
                                    .ToList();