[英]C# Comparing two lists of lists of objects
我不知道我在哪里犯錯,但是我無法比較(例如)整數列表的兩個列表。
簡單的例子:
List<List<int>> A = new List<List<int>>();
A.Add(new List<int>(new int[] { 1 }));
A.Add(new List<int>(new int[] { 2 }));
List<List<int>> B = new List<List<int>>();
B.Add(new List<int>(new int[] { 1 }));
if (A.Contains(B[0])){
Console.WriteLine("TRUE");
else{
Console.WriteLine("FALSE");
}
返回False。 在這種情況下進行比較的正確方法是什么? 我也嘗試了Intersect
和Except
相同的結果。
您可以遍歷A中的每個列表,並使用SequenceEqual將其與B [0]進行比較:
if (A.Any(list => list.SequenceEqual(B[0])))
{
Console.WriteLine("TRUE");
}
else
{
Console.WriteLine("FALSE");
}
將返回true
bool contains = A.Any(a => B.Any(b => b.OrderBy(x => x)
.SequenceEqual(a.OrderBy(x => x))));
[[1],[2]] and [[3]] => false
[[1],[2]] and [[1]] => true
[[2],[1]] and [[1],[2]] => true
[[3],[4]] and [[1],[2]] => false
[[1,2],[3]] and [[2,1],[4]] => true
這可能有助於形象化:
A:
A[0]:
A[0][0]: 1
A[1]:
A[1][0]: 2
B:
B[0]:
B[0][0]: 1
調用A.Contains()
,您正在詢問要測試的對象是A[0]
還是A[1]
。 由於您要傳遞B
,並且B
都不是這兩個,因此它返回false。 即使您將其傳遞給B[0]
或B[0][0]
,您仍然會得到false,因為這些都不是與 A[0]
或A[1]
相同的對象 。
SequenceEqual()
函數將測試兩個List
的內容是否相同。 所以要測試是否任一A[0]
或A[1]
是SequenceEqual
到B[0]
(即,或者A[0][0] == B[0][0]
或A[1][0] == B[0][0]
)。
最好的方法是使用LINQ函數.Any()
。 A.Any(a => a.SequenceEqual(B[0]))
將針對A
中的所有內容測試B[0]
。 如果要比較所有 B
元素和所有 A
元素,則需要更多類似A.Any(a => B.Any(b => a.SequenceEqual(b))
可以轉換為:
foreach (var a in A) // A[0], A[1], etc.
{
foreach (var b in B) // B[0], B[1], etc.
{
// is our current a value matching the current b value?
// i.e. A[0] is exactly the same as B[0] on the first pass
if (a.SequenceEqual(b)) return true;
}
}
return false;
對於字符串以外的引用類型,如果operator ==的兩個操作數引用同一對象,則其返回true。 顯然,這里要比較一個列表引用和另一個列表引用的情況並非如此。
您正在比較列表,默認情況下會比較這些列表以確保引用相等。 對於這種特殊情況,您可以通過以下方式使用SequenceEqual
擴展:
bool contains = A.Any(a => a.SequenceEqual(B[0]));
Console.WriteLine(contains);
對於您的目的而言,這可能會或可能不夠高效:)
解決此問題的另一種方法是圍繞SequenceEqual
編寫您自己的IEqualityComparer
包裝,如下所述: .Contains
IEqualityComparer ,然后將其用作.Contains
調用中的參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.