在 C# 中,查看列表是否包含另一个列表的最佳方法是什么

本文关键字:列表 另一个 最佳 方法 是什么 包含 是否 | 更新日期: 2023-09-27 18:37:24

如果我有一个字符串列表,那么确定另一个列表中的每个元素是否包含在此列表中的最佳方法是什么? 例如:

List<string> list = new List<string>();
list.Add("Dog");
list.Add("Cat");
list.Add("Bird");
List<string> list2 = new List<string>();
list.Add("Dog");
list.Add("Cat");
if (list.ContainsList(list2))
{
      Console.Write("All items in list2 are in list1")
}  

我正在尝试确定是否有类似这种"包含列表"方法的东西?

在 C# 中,查看列表是否包含另一个列表的最佳方法是什么

if (!list2.Except(list).Any())

喜欢 SLaks 版本。为了完整起见,您可以在执行集合操作时使用HashSet方法 IsSubsetOf (也请检查IsSupersetOf方法)。这种方法有利有弊。下一个代码显示了一个示例:

var list1 = new HashSet<string>{ "Dog", "Cat", "Bird" };
var list2 = new HashSet<string>{ "Dog", "Cat" };
if (list2.IsSubsetOf(list1))
{
      Console.Write("All items in list2 are in list1");
}  

Except方法本质上是流式传输。在查询中,list2.Except(list1) list1完全缓冲到内存中,并且您一次通过list2循环访问一个项目。 IsSubsetOf急切地以相反的方式工作。当您拥有大量数据集时,这开始产生影响。


为了分析最坏情况的性能,这里有一些来自Monos Enumerable Except实现的代码(dotPeek给出了非常相似的结果,只是可读性较差)

var items = new HashSet<TSource> (second, comparer);  //list1.Count
foreach (var element in first)                        //list2.Count
    if (items.Add (element))                          //constant time
        yield return element;

结果O(list1.Count + list2.Count),循环不是嵌套的。

IsSubset有下一个方法调用,如果第二个IEnumerableHashSet(通过dotPeek反编译):

private bool IsSubsetOfHashSetWithSameEC(HashSet<T> other)
{
    foreach (T obj in this)         //list2.Count
        if (!other.Contains(obj))   //constant time
            return false;
    return true;
}

如果list1HashSet,则会导致O(list2.Count)

怎么样

var list1 = new List<string>{"Dog","Cat","Bird"};
var list2 = new List<string>{"Dog","Cat"};
if (list1.Union(list2).SequenceEqual(list1))
    Console.Write("All items in list2 are in list1");
这个

怎么样

list1.intersect (list2).ToList ().Foreach ((x)=>
{
Console.Writeline (x)
});