2009-10-05 53 views
68

tôi có phương pháp sau đây:.NET có cách kiểm tra xem Danh sách chứa tất cả các mục trong Danh sách b không?

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); 
      }); 
     } 
    } 
} 

Mục đích của nó là để xác định xem một danh sách chứa tất cả các yếu tố của một danh sách khác. Nó sẽ xuất hiện với tôi rằng một cái gì đó như thế này sẽ được xây dựng vào. NET đã, đó là trường hợp và tôi đang nhân bản chức năng?

Chỉnh sửa: Lời xin lỗi của tôi vì không nêu rõ rằng tôi đang sử dụng mã này trên phiên bản Mono 2.4.2.

+0

Xem thêm https://stackoverflow.com/questions/332973/check-whether-an-array-is-a -subset-of-another –

+0

Thuật toán của bạn là bậc hai O (nm). Nếu các danh sách được sắp xếp, kiểm tra xem một danh sách có phải là tập hợp con của một danh sách khác có thể được thực hiện trong thời gian O (n + m) hay không. –

Trả lời

126

Nếu bạn đang sử dụng .NET 3.5, thật dễ dàng:

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

này kiểm tra xem có bất kỳ yếu tố trong b mà không phải là trong a - và sau đó đảo ngược kết quả.

Lưu ý rằng nó sẽ là một chút thông thường hơn để làm cho phương pháp chung chứ không phải là lớp học, và không có lý do để yêu cầu List<T> thay vì IEnumerable<T> - vì vậy đây có lẽ được ưa thích:

public static class LinqExtras // Or whatever 
{ 
    public static bool ContainsAllItems<T>(IEnumerable<T> a, IEnumerable<T> b) 
    { 
     return !b.Except(a).Any(); 
    } 
} 
+0

Điều này chưa được kiểm tra, nhưng sẽ không trả lại b.Except (a) .Empty(); có thể đọc được nhiều hơn không? – Nils

+7

Trừ trường hợp Empty() không trả về boolean. Nó trả về một số không thể đếm được là không có mặt hàng nào. –

+0

Điều này yêu cầu LINQ phải không? Nếu vậy, tôi không nghĩ rằng đó là có sẵn trong Mono, đó là những gì tôi đang sử dụng vào lúc này. –

29

Just để giải trí, hãy xem answer của JonSkeet như một phương thức mở rộng:

/// <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(); 
} 
+2

+1 cho công việc phụ – jeremy

+2

tương tự: Chứa Any = 'public static bool ContainsAny (IEnumerable haystack, IEnumerable kim) {return haystack.Intersect (needle) .Count()> 0; } '. Tôi đã thử một số so sánh hiệu suất nhanh chóng để 'haystack.Count() - 1> = haystack.Except (kim) .Count();' và 'Intersect' dường như làm tốt hơn hầu hết thời gian. – drzaus

+3

sheesh ... sử dụng 'Any()' không 'Count()> 0':' public static bool ContainsAny (IEnumerable haystack, IEnumerable kim) {return haystack.Intersect (kim).Bất kì(); } ' – drzaus

0

Bạn cũng có thể sử dụng cách khác. Ghi đè bằng và sử dụng này

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; 
    } 
} 
+2

' danh sách l = danh sách mới (kiểm tra); 'Tôi không nghĩ rằng điều này sẽ biên dịch và nếu có, nó hoàn toàn không cần thiết như' kiểm tra' đã là một danh sách –

13

Bao gồm trong .NET 4: Enumerable.All

public static bool ContainsAll<T>(IEnumerable<T> source, IEnumerable<T> values) 
{ 
    return values.All(value => source.Contains(value)); 
} 
Các vấn đề liên quan