簡體   English   中英

如何從對象列表中獲取不同的列表?

[英]How to get a distinct list from a List of objects?

我有一個List<MyClass> someList

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

我想知道如何從List<MyClass> someList獲得一個新的不同List<MyClass> distinctList ,但只將它與Prop2進行比較。

您可以使用GroupBy模擬DistinctBy的效果,然后僅使用每個組中的第一個條目。 雖然可能比其他實現慢一點。

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

不幸的是,在框架中並沒有真正簡單的內置支持——但您可以使用我在MoreLINQ中的DistinctBy實現。

你會使用:

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

(您可以只采用DistinctBy實現。如果您更願意使用 Microsoft 實現,我相信Reactive Extensions的 System.Interactive 程序集中有類似的東西。)

你需要使用.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());

覆蓋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();
    }
}

然后只需調用:

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

自從引入了值元組,如果你想要一個相當於 SQL 的 DISTINCT 的 LINQ

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

如果你想通過多個字段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();

創建一個實現IEqualityComparer接口的類,該接口僅檢查您的 Prop2-Property。 然后,您可以將此類的實例傳遞給 Distinct 擴展方法。

我知道這已經有一段時間了,但我需要最簡單的答案,此時(使用 .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 對象添加到字典中的鍵(長)對於 FileModel 是唯一的)。

*為示例中的清晰起見命名。

關鍵是我在 ConcurrentDictionary 中有大量的 FileModel(假設有 100 個),在這 100 個 FileModel 中有 5 個不同的 groupId。

此時我只需要一個不同 groupId 的列表。

所以,如果我只有一個 FileModel 列表,代碼將如下所示:

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

我有一個List<MyClass> someList

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

我想知道如何從List<MyClass> someList獲得一個新的不同List<MyClass> distinctList ,但只將它與Prop2進行比較。

刪除所有屬性都相等的重復項的簡單方法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM