簡體   English   中英

在LINQ中使用Union合並列表時刪除重復項

[英]Remove duplicates while merging lists using Union in LINQ

我試圖在LinqPad中使用list.Union合並兩個列表,但我無法讓它工作,並想檢查我的理解是否正確。

鑒於這個簡單的類:

public class Test 
{
   public int Id { get; set;}
   public int field1 { get; set; }

   public bool Equals(Test other)
   {        
      return this.Id.Equals(other.Id);
   }
}

兩個列表填充如下:

List<Test> list = new List<Test>();
list.Add( new Test { Id = 1, field1 = 1});
list.Add( new Test { Id = 1, field1 = 2});
list.Add( new Test { Id = 2, field1 = 3});
list.Add( new Test { Id = 2, field1 = 4});

List<Test> list2 = new List<Test>();
list2.Add( new Test { Id = 1, field1 = 1});
list2.Add( new Test { Id = 1, field1 = 2});
list2.Add( new Test { Id = 2, field1 = 3});
list2.Add( new Test { Id = 2, field1 = 4});

然后我嘗試: var mergedList = list.Union(list2).ToList(); 並使用簡單的foreach循環輸出數據並獲得此輸出:

ID: 1 -------- 1
ID: 1 -------- 2
ID: 2 -------- 3
ID: 2 -------- 4
ID: 1 -------- 1
ID: 1 -------- 2
ID: 2 -------- 3
ID: 2 -------- 4

我認為Union應該刪除重復的回復:

ID: 1 -------- 1
ID: 1 -------- 2
ID: 2 -------- 3
ID: 2 -------- 4

我做錯了什么或者我誤解了嗎?

此外,它是否可以在沒有顯式覆蓋Test類中的Equals方法的情況下工作?

謝謝

在您的情況下,您只需定義一些LINQ一無所知的方法。 這就像創建方法bool HeyEquateMeWith(Test other)並期望LINQ在執行set操作時會調用它。

您需要將您的類定義如下( 覆蓋 ObjectEqualsGetHashCode方法):

public class Test 
{
   public int Id { get; set;}
   public int field1 { get; set; }  

   public override bool Equals(object other) //note parameter is of type object
   {        
        Test t = other as Test;
        return (t != null) ? Id.Equals(t.Id) : false;
   }

   public override int GetHashCode()
   {
        return Id.GetHashCode();
   }
}

現在Union將調用您重寫的EqualsGetHashCode方法。 當你重寫Equals方法時,你應該總是覆蓋GetHashCode

您可以創建一個實現類

IEqualityComparer<Test>

這個類是否定義了Equals和GetHashCode之后你可以將這個比較器傳遞給你的Union方法就像這樣:

public class MyComparer:IEqualityComparer<Test>{
//Equals and GetHashCode
}

var mergedList = list.Union(list2, new MyComparer()).ToList();

只想把它留在這里給那些仍然無法得到它的人。 我發現這篇文章對繼承自IEqualityComparer的比較類非常有幫助http://alicebobandmallory.com/articles/2012/10/18/merge-collections-without-duplicates-in-c

你可以嘗試類似的東西,如果不滿意默認比較器(反過來,利用GetHashCode方法,如@IlyaIvanov提到的):

// get all items that "other than in first list", so Where() and Any() are our filtering expressions
var delta = list2.Where(x2 => !list.Any(x1 => (x1.Id == x2.Id) && (x1.field1 == x2.field1)));

// now let merge two enumerables that have nothing "equal" between them
var merged = list.Union(delta).ToList();

暫無
暫無

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

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