2014-09-19 168 views
1

我想比較兩個對象列表。這些列表包含相同類型的對象。我在我的程序中創建一個新的列表,我想在數據庫中的舊列表中進行比較。我用存儲過程得到它,然後把它放到一個對象中。比較兩個對象列表C#

The old list :      the new list : 

*Category 1*       Category 5 
*Category 2*       Category 6 
*Category 3*       *Category 4* 
Category 4 

這裏的目的是刪除前三個類別中的舊列表,東陽他們不會在新的列表中存在。並且爲了刪除新列表中的類別4,因爲類別4已經存在於舊列表中。

可以使用類似Equals()的à方法或使用兩個foreach循環來瀏覽列表?

感謝您的答案和建議

+0

你試過'.Except()'擴展方法嗎? – 2014-09-19 08:55:38

+0

我試過,但是,問題是我不使用對象的所有屬性,它不工作。可以選擇要比較的屬性? – Julien698 2014-09-19 09:06:20

+1

Except()方法可以採用必須實現的IEqualityComparer(http://msdn.microsoft.com/zh-cn/library/vstudio/ms132151%28v=vs.100%29.aspx)。它應該執行你想要的比較。 – 2014-09-19 09:09:56

回答

3

您可以使用LINQ,exceptwhere

var a = new List<string> { "a", "b", "c" }; 
var b = new List<string> { "c", "d", "e" }; 
var temp = a.Intersect(b).ToList(); 
b = b.Except(a).ToList(); 
a = temp; 

輸出:

a: "c" 
b: "d", "e" 

注:這可能是更有效的,如果你這樣做沒有LINQ

var a = new List<string> { "a", "b", "c" }; 
var b = new List<string> { "c", "d", "e" }; 

for(int i = 0; i < a.Count; i++) 
    if(b.Contains(a[i])) 
     b.Remove(a[i]); 
    else 
     a.Remove(a[i--]); 

需要根據特定值

01進行比較
for(int i = 0; i < a.Count; i++) 
{ 
    var obj = b.Where(item => item.Category == a[i].Category); 
    if(obj.Any()) 
     b.Remove(obj.First()); 
    else 
     a.Remove(a[i--]); 
} 
+2

你可以使用'Intersect'而不是'Where' /'Contains'組合。例如:'var temp = a.Intersect(b).ToList();' – LukeH 2014-09-19 09:09:22

+0

@LukeH - 謝謝,我忘了'Intersect' – Sayse 2014-09-19 09:10:34

+0

這是一個好主意,它工作正常,但我有anonther問題,它的對象屬性不一樣。例如,我的Title = Category1,Id = 2,rank = 4,另一個Title = Category1,Id = 2,rank = 0.因爲Rank不匹配。我認爲我會解決排名問題,一直把它歸爲零! – Julien698 2014-09-19 09:29:06

0

我會通過排序兩個列表,並遍歷第一和第二列表解決這個問題。我會將第一個列表的當前項目與第二個當前項目進行比較。如果找到匹配項,我從第二個列表中刪除匹配項,然後移動到兩個列表中的下一個項目,否則將刪除第一個列表中的當前項目,迭代繼續在第一個列表中。

+0

是什麼讓你覺得他們可以排序? – Rawling 2014-09-19 09:02:08

1

它不是最漂亮的實現,但你可以做到這一點的最快方法是:

var tempA = new HashSet<int>(inputA.Select(item => item.Id)); 
var tempB = new HashSet<int>(inputB.Select(item => item.Id)); 

var resultA = new List<Category>(inputA.Count); 
var resultB = new List<Category>(inputB.Count); 

foreach (var value in inputA) 
    if (tempB.Contains(value.Id)) 
     resultA.Add(value); 

foreach (var value in inputB) 
    if (!tempA.Contains(value.Id)) 
     resultB.Add(value); 

resultA.TrimExcess(); 
resultB.TrimExcess(); 

// and if needed: 
inputA = resultA; 
inputB = resultB; 

如果您需要超過item.id獨特然後用一個新的記錄,如:

inputA.Select(item => new Tuple<int, string>(item.Id, item.Title)); 

另一種選擇是在你的類類重寫.GetHashCode如:

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

public override bool Equals(object obj) 
{ 
    var typedObj = obj as Category; 
    if (typedObj == null) 
     return false; 
    return Title == typedObj.Title && Id == typedObj.Id && Rank == typedObj.Rank; 
}