查找列表中不存在于另一个列表中的元素的最有效方法是什么?反之亦然

本文关键字:列表 方法 是什么 反之亦然 有效 元素 不存在 另一个 查找 | 更新日期: 2024-09-24 15:04:11

考虑C#中有两个列表,第一个列表包含TypeOne的元素,第二个列表包含TypeTwo:的元素

TypeOne
{  
    int foo;  
    int bar;  
}
TypeTwo
{  
    int baz;  
    int qux;  
}

现在,我需要在第一个列表中查找第二个列表中不存在的元素(具有某些属性值),同样,我也希望在第二个名单中查找第一个名单中不存在。(两个列表中只有零次或一次出现。)

到目前为止,我尝试的是这样迭代两个列表:

foreach (var item in firstList)
{
    if (!secondList.Any(a=> a.baz == item.foo)
    {
        // Item is in the first list but not in second list.
    }
}

再次:

foreach (var item in secondList)
{
    if (!firstList.Any(a=> a.foo == item.baz)
    {
        // Item is in the second list but not in first list.
    }
}

我觉得这不是做我想做的事的好方法。我对我的列表进行了两次迭代,并在每个列表中使用Any,这也会迭代列表。迭代太多了。

实现这一目标的最有效方法是什么?

查找列表中不存在于另一个列表中的元素的最有效方法是什么?反之亦然

恐怕没有预构建的解决方案,所以我们能做的最好的事情就是尽可能多地优化。我们只需要迭代第一个列表,因为第二个列表中的所有内容都将被比较

// First we need copies to operate on
var firstCopy = new List<TypeOne>(firstList);
var secondCopy = new List<TypeTwo>(secondList);
// Now we iterate the first list once complete
foreach (var typeOne in firstList)
{
    var match = secondCopy.FirstOrDefault(s => s.baz == typeOne.foo);
    if (match == null)
    {
        // Item in first but not in second
    }
    else
    {
        // Match is duplicate and shall be removed from both
        firstCopy.Remove(typeOne);
        secondCopy.Remove(match);
    }
}

运行后,两个副本将只包含在此实例中唯一的值。这不仅将迭代次数减少到一半,而且由于第二个副本随着每次匹配而缩小,因此不断改进。

使用此LINQ查询。

  var result1 = secondList.Where(p2 => !firstList.Any(p1 => p1.foo == p2.baz));
  var result2=firstList.Where(p1=> !secondList.Any(p2=> p2.foo == p1.baz);