.NET 是不是有办法检查列表 a 是不是包含列表 b 中的所有项目?

Posted

技术标签:

【中文标题】.NET 是不是有办法检查列表 a 是不是包含列表 b 中的所有项目?【英文标题】:Does .NET have a way to check if List a contains all items in List b?.NET 是否有办法检查列表 a 是否包含列表 b 中的所有项目? 【发布时间】:2010-12-03 23:41:22 【问题描述】:

我有以下方法:

namespace ListHelper

    public class ListHelper<T>
    
        public static bool ContainsAllItems(List<T> a, List<T> b)
        
            return b.TrueForAll(delegate(T t)
            
                return a.Contains(t);
            );
        
    

其目的是确定一个列表是否包含另一个列表的所有元素。在我看来,这样的东西已经内置到 .NET 中了,是这样吗?我是否在复制功能?

编辑:我很抱歉没有预先说明我在 Mono 2.4.2 版上使用此代码。

【问题讨论】:

另见***.com/questions/332973/… 你的算法是二次 O(nm)。如果列表已排序,则应该可以在 O(n+m) 时间内测试一个是否是另一个的子集。 【参考方案1】:

我知道一种使用 LinQ 方法的方法。读起来有点奇怪,但效果很好

var motherList = new List<string>  "Hello", "World", "User ;
var sonList = new List<string>  "Hello", "User" ;

你想检查sonList是否完全在motherList中

这样做:

sonList.All(str => moterList.Any(word => word == str));

// Reading literally, would be like "For each of all items 
// in sonList, test if it's in motherList

请检查一下,看看那里是否也有效。希望它有所帮助;-)

【讨论】:

【参考方案2】:

如果您使用的是 .NET 3.5,这很容易:

public class ListHelper<T>

    public static bool ContainsAllItems(List<T> a, List<T> b)
    
        return !b.Except(a).Any();
    

这会检查b 中是否有任何不在a 中的元素 - 然后反转结果。

请注意,将 method 设为泛型而不是类会稍微传统一些,并且没有理由需要 List&lt;T&gt; 而不是 IEnumerable&lt;T&gt; - 所以这可能是首选:

public static class LinqExtras // Or whatever

    public static bool ContainsAllItems<T>(this IEnumerable<T> a, IEnumerable<T> b)
    
        return !b.Except(a).Any();
    

【讨论】:

这是未经测试的,但不会返回 b.Except(a).Empty();更具可读性? 除了 Empty() 不返回布尔值。它返回一个没有项目的 IEnumerable 您可以在 Mono 中使用 LINQ to Objects,我相信……但如果您在开始时说明问题中的要求会很有帮助。您使用的是哪个版本的 Mono? 如果列表长度为n和m,这个算法的时间复杂度是多少? @ColonelPanic:假设没有哈希冲突,O(n+m)。【参考方案3】:

包含在 .NET 4 中:Enumerable.All

public static bool ContainsAll<T>(IEnumerable<T> source, IEnumerable<T> values)

    return values.All(value => source.Contains(value));

【讨论】:

【参考方案4】:

您也可以使用其他方式。覆盖等于并使用它

public bool ContainsAll(List<T> a,List<T> check)

   list l = new List<T>(check);
   foreach(T _t in a)
   
      if(check.Contains(t))
      
         check.Remove(t);
         if(check.Count == 0)
         
            return true;
         
      
      return false;
   

【讨论】:

list l = new List&lt;T&gt;(check); 我不认为这会编译,如果可以,它完全没有必要因为check 已经是一个列表【参考方案5】:

只是为了好玩,@JonSkeet 的 answer 作为扩展方法:

/// <summary>
/// Does a list contain all values of another list?
/// </summary>
/// <remarks>Needs .NET 3.5 or greater.  Source:  https://***.com/a/1520664/1037948 </remarks>
/// <typeparam name="T">list value type</typeparam>
/// <param name="containingList">the larger list we're checking in</param>
/// <param name="lookupList">the list to look for in the containing list</param>
/// <returns>true if it has everything</returns>
public static bool ContainsAll<T>(this IEnumerable<T> containingList, IEnumerable<T> lookupList) 
    return ! lookupList.Except(containingList).Any();

【讨论】:

类似地:包含 Any = public static bool ContainsAny&lt;T&gt;(this IEnumerable&lt;T&gt; haystack, IEnumerable&lt;T&gt; needle) return haystack.Intersect(needle).Count() &gt; 0; 。我尝试了一些与haystack.Count() - 1 &gt;= haystack.Except(needle).Count();Intersect 的快速性能比较,似乎大多数时候都做得更好。 嘘...使用Any() 而不是Count() &gt; 0: public static bool ContainsAny&lt;T&gt;(this IEnumerable&lt;T&gt; haystack, IEnumerable&lt;T&gt; needle) return haystack.Intersect(needle).Any();

以上是关于.NET 是不是有办法检查列表 a 是不是包含列表 b 中的所有项目?的主要内容,如果未能解决你的问题,请参考以下文章

检查对象参数是不是包含字母列表

Pyspark:检查数组类型列是不是包含列表中的值[重复]

检查列表是不是包含与某些东西不同的元素[重复]

EF CORE PostgreSQL - 检查列表的所有元素是不是包含在另一个列表中

Python检查列表项是不是(不)包含任何其他列表项

列表理解,检查项目是不是唯一