使用对象属性的linq获取不同或分组列表

本文关键字:列表 获取 对象 属性 linq | 更新日期: 2023-09-27 18:03:34

我有

List<ObjA>  
ObjA has ObjB  
ObjB has property Id  

如何获得基于Id的不同ObjB列表?

谢谢

使用对象属性的linq获取不同或分组列表

使用DistinctBy from MoreLinq,你可以这样使用:

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

您需要创建自己的IEqualityComparer<ObjB>来仅使用其Id属性来比较objb。然后你可以这样做:

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

如果您在ObjB上重写了.Equals(),使具有相同ID的项被认为是相等的(而具有不同ID的项被认为是不相等的),您可以

var list = GetListOfAs();
var distinctBs = list.Select(a => a.B).Distinct();

正如Daniel Hilgarth在他的回答中指出的,有一个名为MoreLINQ的扩展库,其中有一个名为DistinctBy的方法。这样,您根本不需要重写Equals -相反,只需调用

var distinctBs = list.Select(a => a.B).DistinctBy(b => b.ID);
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

这里有一个不需要扩展的解决方案:

List<ObjB> distinctObjB = lst
  .GroupBy(a => a.MyObjB.Id)
  .Select(b => b.First().MyObjB)
  .ToList();