क्या .NET के पास यह जाँचने का एक तरीका है कि सूची में सभी आइटम हैं सूची b?


98

मेरे पास निम्न विधि है:

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 में बनाया जाएगा, क्या यह मामला है और क्या मैं कार्यक्षमता की नकल कर रहा हूं?

संपादित करें: सामने वाले को यह न बताने के लिए मेरी क्षमा याचना कि मैं मोनो कोड 2.4.2 पर इस कोड का उपयोग कर रहा हूं।



आपका एल्गोरिथ्म द्विघात O (nm) है। यदि सूचियों को क्रमबद्ध किया जाता है, तो यदि किसी का सबसेट है तो परीक्षण O (n + m) समय में संभव होना चाहिए।
कर्नल पैनिक

जवाबों:


176

यदि आप .NET 3.5 का उपयोग कर रहे हैं, तो यह आसान है:

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

यह जाँचता है कि क्या ऐसे कोई तत्व हैं bजिनमें a- नहीं हैं और फिर परिणाम का विरोध करता है।

ध्यान दें कि वर्ग के बजाय विधि को सामान्य बनाने के लिए यह थोड़ा अधिक पारंपरिक होगा , और List<T>इसके बजाय इसकी आवश्यकता का कोई कारण नहीं है IEnumerable<T>- इसलिए यह संभवतः पसंद किया जाएगा:

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

1
यह अप्रयुक्त है, लेकिन b.Except (a) .Empty () नहीं लौटेगा; बहुत अधिक पठनीय हो?
Nils

7
सिवाय इसके कि खाली () एक बूलियन वापस नहीं करता है। यह कोई आइटम के साथ एक IEnumerable <T> देता है।
पीटर स्टीफेंस

2
आप LINQ का उपयोग मोनो में ऑब्जेक्ट्स के लिए कर सकते हैं, मेरा मानना ​​है कि ... लेकिन यह उपयोगी होगा यदि आप शुरू करने के लिए प्रश्न में आवश्यकताओं को बताएंगे। आप मोनो के किस संस्करण का उपयोग कर रहे हैं?
जॉन स्कीट

1
यदि सूचियां लंबाई n और m हैं, तो इस एल्गोरिथ्म की समय जटिलता क्या है?
कर्नल पैनिक

1
@ColonelPanic: कोई हैश टकराव मानते हुए, O (n + m)।
जॉन स्कीट

37

.NET 4 में शामिल: Enumerable.All

public static bool ContainsAll<T>(IEnumerable<T> source, IEnumerable<T> values)
{
    return values.All(value => source.Contains(value));
}

35

बस मज़े के लिए, @ जोन्स्केट का जवाब एक विस्तार विधि के रूप में:

/// <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
इसी तरह: किसी भी शामिल = public static bool ContainsAny<T>(this IEnumerable<T> haystack, IEnumerable<T> needle) { return haystack.Intersect(needle).Count() > 0; }। मैंने कुछ त्वरित प्रदर्शन तुलनाओं की कोशिश की haystack.Count() - 1 >= haystack.Except(needle).Count();और Intersectज्यादातर समय बेहतर करने के लिए लग रहा था।
प्रातः 16:13

4
शीश ... उपयोग Any()नहीं Count() > 0: public static bool ContainsAny<T>(this IEnumerable<T> haystack, IEnumerable<T> needle) { return haystack.Intersect(needle).Any(); }
drzaus

0

आप दूसरा तरीका भी इस्तेमाल कर सकते हैं। समतुल्य को ओवरराइड करें और इसका उपयोग करें

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
list l = new List<T>(check);मुझे नहीं लगता कि यह संकलन होगा और अगर ऐसा होता है, तो यह पूरी तरह से जरूरी है क्योंकि checkपहले से ही एक सूची है
रोहित विपिन मैथ्यूज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.