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

时间:2011-02-14 11:42:53

标签: c# linq class list properties

我有List<MyClass> someList

class MyClass
{
    public int Prop1...
    public int Prop2...
    public int Prop3...
}

我想知道如何从List<MyClass> distinctList获取新的不同List<MyClass> someList,但只将其与Prop2进行比较。

10 个答案:

答案 0 :(得分:82)

您可以使用DistinctBy模拟GroupBy的效果,然后只使用每个组中的第一个条目。可能会比其他实现慢一点。

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());

答案 1 :(得分:47)

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

您将使用:

var distinctList = someList.DistinctBy(x => x.Prop2).ToList();

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

答案 2 :(得分:19)

您需要使用.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;
        }
    }

不要忘记GetHashCode

用法:

List<Point> p = new List<Point>();
// add items
p.Distinct(new Comparer());

答案 3 :(得分:11)

覆盖等于(对象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();
    }
}

然后只需致电:

List<MyClass> distinctList = someList.Distinct().ToList();

答案 4 :(得分:2)

创建一个实现IEqualityComparer接口的类,该接口仅检查您的Prop2-Property。然后,您可以将此类的实例传递给Distinct扩展方法。

答案 5 :(得分:1)

<强>七。年份。后

我知道已经有一段时间了,但我需要最简单的答案,此时(使用.NET 4.5.1)我发现以下内容是我能得到的最直接的答案:

IEnumerable<long> allIds = waitingFiles.Values.Select(wf => wf.groupId).Distinct();

我的情况是我有一个ConcurrentDictionary看起来像: ConcurrentDictionary<long, FileModel>

ConcurrentDictionary Values属性基本上是我的List<FileModel>

* FileModel有一个groupId,它不一定是唯一的(但是,显然我用来将FileModel对象添加到字典中的键(long)对于FileModel是唯一的。)

*为了清楚起见,在示例中命名。

关键是我在ConcurrentDictionary中有大量的FileModel(想象100),在这100个FileModel中有5个不同的groupIds。

此时我只需要一个不同的groupId列表。

所以,如果我只有一个FileModel列表,代码将如下所示:

IEnumerable <long> allIds = allFileModel.Select(fm => fm.groupId).Distinct();

答案 6 :(得分:1)

自从引入值元组以来,如果要使用与SQL的DISTINCT等效的LINQ

items.GroupBy(item => (item.prop1, item.prop2, ...)).Select(group => group.First())

答案 7 :(得分:0)

只需使用Microsoft Ajax Ultility库的内置函数DistinctBy,如示例打击:

首先包含库

using Microsoft.Ajax.Utilities;

然后

var distinctList = yourList.DistinctBy(x => x.Prop2).ToList();

答案 8 :(得分:0)

如果您想通过多个字段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();
    }
}

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

var distinctedList = myList.Distinct(new MyComparer()).ToList();

答案 9 :(得分:0)

删除所有属性均相同的重复项的简单方法:

System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();
serviceList = serviceList.GroupBy(s => jss.Serialize(s)).Select(group => group.First()).ToList();