【问题标题】: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 版上使用此代码。

【问题讨论】:

标签: c# .net list generics mono


【解决方案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://stackoverflow.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(); }
      猜你喜欢
      • 2012-09-04
      • 1970-01-01
      • 2021-07-23
      • 2019-06-13
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多