Valamas
Valamas

Reputation: 24719

Get distinct or groupby list using linq of object property

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

Answers (5)

marapet
marapet

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

Grozz
Grozz

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

thecoop
thecoop

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

Tomas Aschan
Tomas Aschan

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

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174289

Using DistinctBy from MoreLinq, you can use this:

list.Select(a => a.ObjB).DistinctBy(b => b.Id);

Upvotes: 3

Related Questions