如何从对象列表中获取不同的列表?

Wil*_*lem 46 c# linq properties class list

我有一个List<MyClass> someList.

class MyClass
{
    public int Prop1...
    public int Prop2...
    public int Prop3...
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何获得一个新的唯一List<MyClass> distinctListList<MyClass> someList,但它只是比较Prop2.

Cod*_*aos 93

你可以模仿的效果DistinctByGroupBy,然后就利用每个组中的第一项.可能会比其他实现慢一点.

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());
Run Code Online (Sandbox Code Playgroud)

  • 也适用于多个属性:`someList.GroupBy(elem => new {elem.Prop1,elem.Prop2,elem.Prop3}).选择(group => group.First());` (16认同)
  • 这应该是已经接受的答案.它不依赖于任何外部库和清洁 (2认同)

Jon*_*eet 53

不幸的是,在框架中没有非常简单的内置支持 - 但你可以使用DistinctBy我在MoreLINQ中的实现.

你用的是:

var distinctList = someList.DistinctBy(x => x.Prop2).ToList();
Run Code Online (Sandbox Code Playgroud)

(您可以只DistinctBy执行实现.如果您更愿意使用Microsoft实现,我相信Reactive Extensions的System.Interactive程序集中有类似的东西.)

  • @Ilya:这很简单:`foo.DistinctBy(x => new {x.Prop1,x.Prop2});` (5认同)

Ily*_*gin 20

你需要使用.Distinct(..);扩展方法.这是一个快速示例:

public class Comparer : IEqualityComparer<Point>
    {
        public bool Equals(Point x, Point y)
        {
            return x.X == y.X;
        }

        public int GetHashCode(Point obj)
        {
            return (int)obj.X;
        }
    }
Run Code Online (Sandbox Code Playgroud)

别忘了GetHashCode.

用法:

List<Point> p = new List<Point>();
// add items
p.Distinct(new Comparer());
Run Code Online (Sandbox Code Playgroud)

  • 如果我们调用`p.Distinct();`而没有`new Comparer()`参数会发生什么?一般来说`ListOfObjects.Distinct()`如何工作? (2认同)

Wal*_*ski 13

覆盖Equals(object obj)GetHashCode()方法:

class MyClass
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }

    public override bool Equals(object obj)
    {
        return ((MyClass)obj).Prop2 == Prop2;
    }
    public override int GetHashCode()
    {
        return Prop2.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后打电话:

List<MyClass> distinctList = someList.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)


hng*_*r18 7

自从引入了值元组之后,如果你想要一个相当于SQL的DISTINCT的LINQ

items.GroupBy(item => (item.prop1, item.prop2, ...)).Select(group => group.First())
Run Code Online (Sandbox Code Playgroud)


Mas*_*ian 6

如果您想按Distinct多个字段列出列表,则必须创建一个IEqualityComparer接口实例:

public class MyComparer : IEqualityComparer<MyModel>
{
    public bool Equals(MyModel x, MyModel y)
    {
       // compare multiple fields
        return
            x.Field1 == y.Field1 &&
            x.Field2 == y.Field2 &&
            x.Field3 == y.Field3 ;
    }

    public int GetHashCode(MyModel obj)
    {
        return 
            obj.Field1.GetHashCode() + 
            obj.Field2.GetHashCode() + 
            obj.Field3.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用比较器来区分您的列表:

var distinctedList = myList.Distinct(new MyComparer()).ToList();
Run Code Online (Sandbox Code Playgroud)