如何可能(在我的 C# 例子中)将列表中的元素与列表中的所有其他元素进行比较,但(当然)不与其自身进行比较 - 并对所有元素执行此操作?
示例:
列表A = 新列表 (); Foreach(A 中的某种类型 e_1) { Foreach(A 中的某种类型 e_2) { // 将 e_2 与 A 中除 e_1 之外的其他元素进行比较 } }
这意味着我必须在第二个循环中排除“e_1”,但我该怎么做呢? 当我在第二个循环中使用
Foreach (A.Skip() 中的某种类型 e_2 )时,我必须知道“e_1”的索引。我怎样才能轻松找到这个? 或者还有别的办法吗?
非常感谢:-)
作为一种简单的方法,您可以将
foreach
变成 for
:
for (int i = 0; i < A.Count; ++i) {
var e_1 = A[i];
for (int j = 0; j < A.Count; ++j) {
// We don't compare item with itself
if (i == j)
continue;
var e_2 = A[j];
// compare e_2 to the other elements in A except e_1
}
}
愚蠢的解决方案:使用 for by i 和 for by j 其中 i != j
如果您只需要唯一的项目,请使用 HashSet,如果已经有该项目,hashSet.Add 将返回 false。
如果您想坚持使用
foreach
循环,如果您检测到要比较的两个对象位于同一内存位置,则可以跳过内部循环:
foreach (var e_1 in A)
{
foreach (var e_2 in A)
{
if(Object.ReferenceEquals(e_1, e_2)) continue; //if the objects have the same memory address, skip
// compare e_2 to the other elements in A except e_1
Console.WriteLine($"{e_1} compared to {e_2}");
}
}
使用 Object.ReferenceEquals 不会执行
==
可能执行的任何不必要的较长检查;它只是查询两个参数是否引用内存中的同一个对象。在这里查看它的实际效果:
https://dotnetfiddle.net/AaQBKH
这与
==
略有不同,后者可能会执行更复杂的比较,并在两个对象实际上不同时声明它们相等。您可以在这里看到它的实际效果,其中列表是一堆具有相同内容的 Tuple 对象 ("a",1), ("a",1), ("b",1) - there are two different
("a",1)`:
https://dotnetfiddle.net/0XNSQM
如果您使用ReferenceEquals,那么您会看到第一个
("a",1)
与第二个("a",1)
进行比较,但因为==
执行更深入的比较,查看元组中每个成员的数据内容,==
将发音两个("a",1)
是等价的,即使第二个不是第一个的“本身”等