Reputation: 24719
I have
List<ObjA>
ObjA has ObjB
ObjB has property Id
How do I get a list of distinct ObjB based on Id?
thanks
Upvotes: 2
Views: 2250
Reputation: 56446
Here's a solution without the need of extensions:
List<ObjB> distinctObjB = lst
.GroupBy(a => a.MyObjB.Id)
.Select(b => b.First().MyObjB)
.ToList();
Upvotes: 1
Reputation: 8425
List<ObjA> lst;
// ...
var distinctById = lst.Select(a => a.b) // get all B's
.GroupBy(b => b.id) // group by id's
.Select(g => g.First()); // take one object of each id
Upvotes: 1
Reputation: 46098
You need to create your own IEqualityComparer<ObjB>
to compare ObjBs using only their Id property. Then you can do:
class ObjBEqualityComparer : IEqualityComparer<ObjB> {
public bool Equals(ObjB x, ObjB y) {
return x.Id.Equals(y.Id);
}
public int GetHashCode(ObjB o) {
return o.Id.GetHashCode();
}
}
var objBComparer = new ObjBEqualityComparer();
var result = objAList.Select(o => o.ObjB).Distinct(objBComparer);
Upvotes: 3
Reputation: 60564
If you've overriden .Equals()
on ObjB
so that items with the same ID are considered equal (and items with different ID considered unequal), you can do
var list = GetListOfAs();
var distinctBs = list.Select(a => a.B).Distinct();
As Daniel Hilgarth noted in his answer, there is an extension library called MoreLINQ, in which there is a method called DistinctBy
. With that, you don't need to override Equals
at all - instead, just call
var distinctBs = list.Select(a => a.B).DistinctBy(b => b.ID);
Upvotes: 2
Reputation: 174289
Using DistinctBy from MoreLinq, you can use this:
list.Select(a => a.ObjB).DistinctBy(b => b.Id);
Upvotes: 3