2013-06-18 104 views
2

我遇到了一個我似乎無法包住我的頭的問題。我有兩個相同類型的列表,我需要檢查這些列表是否匹配。我遇到了有關注釋掉for循環和現在正在使用的嵌套foreach循環的問題。我不需要同時使用兩個,一個是我試圖弄清楚這一點。如何比較兩個列表中的項目?

我已經通過調試器運行了這個,發現這兩個列表保存着相同的數據,我假設(使用VS2010調試器)在列表中的相同元素。但是,當它被循環時,它在第一個元素上失敗。

我從類似的問題研究過這個問題,我對LINQ表達式並不是很熟悉(在空閒時我正在做一個研究筆記)。

private bool ListMatch(List<T> list1, List<T> list2) 
    { 
     if (list1 == null && list2 == null) 
     { 
      return true; 
     } 
     if ((list1 == null) || (list2 == null)) 
     { 
      return false; 
     } 
    if (list1.Count != list2.Count) 
    { 
     return false; 
    } 
    if(list1.Equals(list2)) 
    { 
     return true; 
    } 

    /*for (var idx = 0; idx < list1.Count; idx++) 
    { 
     if(list1[ idx ] != list2[ idx ]) 
     { 
      return false; 
     } 
    }*/ 

    foreach(var x in list1) 
    { 
     bool hasDuplicates = false; 
     foreach(var y in list2) 
     { 

      if(x == y) 
      { 
       hasDuplicates = true; 
       break; 
      } 
     } 

     if(hasDuplicates) 
     { 
      return true; 
     } 
     return false; 
    } 

    return true; 
} 
+0

你是比較引用,而不是值。那是你想要做的嗎? –

+0

你的_if(hasDuplicates)_有_return_如果有重複或不是。這就是爲什麼它在第一個元素上失敗。它檢查第一個元素,是否重複?返回true。不是?返回false。它沒有檢查剩下的部分。 – Reyno

+0

我不認爲代碼甚至可以編譯,更不用說執行引用比較了:因爲它們是泛型,所以不能寫'x == y'。 –

回答

1

第二循環有許多錯誤,不使用它^^

可以使用list1.SequenceEqual(list2)檢查列表進行相等(假定順序很重要,它似乎是)。

3

您可以使用Enumerable.SequenceEqual所做的平等手動預檢查後:

private bool ListMatch(List<T> list1, List<T> list2) 
{ 
    if (list1 == null && list2 == null)   
     return true; 

    if ((list1 == null) || (list2 == null))   
     return false;   

    if (list1.Count != list2.Count)  
     return false;  

    if(list1.Equals(list2))   
     return true; 

    return Enumerable.SequenceEqual(list1, list2); 
} 
+1

+1,我會贊成,但我沒有足夠的代表。這與@william解決方案一起給了我更好的理解。我得到一個錯誤的答案(需要它是真實的),但這超出了這個問題的範圍。謝謝! – Matt

0

你不應該使用==,因爲這是默認的參考平等,這聽起來像你的算法確實是失敗的,因爲你要價值平等;使用Object.Equals並覆蓋它。也就是說,framework does this for you(假設您希望兩個列表具有相同順序的相同項目)。用後更換您的循環,一切:

return list1.SequenceEqual(list2); 

你需要確保Object.Equals被覆蓋的元素的列表類型(或他們實施IEquatable<T>),否則你會遇到同樣的問題,因爲一個您代碼中的問題。

另外,還有一個overload,讓你通過如何比較平等我想你需要一些特殊的東西或不想覆蓋Object.Equals

0

您正在比較這些索引中列表的引用。你可以這樣做 Except運算符將返回一個包含這兩個列表中不存在的元素的列表,即差異。這是有用的,如果你需要使用它們的東西

List<T> result = list1.Except(list2).ToList(); 
if (result.count == 0) 
//No differences 
return true; 
else 
//Differences 
return false;