কোনও আইনামেবলে অন্য আইইনামেবলের সমস্ত উপাদান রয়েছে কিনা তা পরীক্ষা করুন


102

উভয় সংকলনের প্রতিটি উপাদানের ক্ষেত্র / সম্পত্তির তুলনা করার সময় একটি আইমনামেবলের মধ্যে অন্য আইমনামেবলের সমস্ত উপাদান রয়েছে কিনা তা নির্ধারণের দ্রুততম উপায় কী?


public class Item
{
    public string Value;

    public Item(string value)
    {
        Value = value;
    }
}

//example usage

Item[] List1 = {new Item("1"),new Item("a")};
Item[] List2 = {new Item("a"),new Item("b"),new Item("c"),new Item("1")};

bool Contains(IEnumerable<Item> list1, IEnumerable<Item>, list2)
{
    var list1Values = list1.Select(item => item.Value);
    var list2Values = list2.Select(item => item.Value);

    return //are ALL of list1Values in list2Values?
}

Contains(List1,List2) // should return true
Contains(List2,List1) // should return false

1
আপনার তালিকাগুলি কোন পথে? আপনি কি তালিকাগুলিতে থাকা সমস্ত আইটেম 2 টি তালিকাতে আছে কিনা বা তালিকার 2 টি আইটেম তালিকায় রয়েছে কিনা তা পরীক্ষা করতে চান?
মার্ক বাইয়ার্স

উত্তর:


138

এটি করার কোনও "দ্রুত উপায়" নেই যদি না আপনি যদি কোনও রাজ্য ট্র্যাক এবং পরিচালনা করেন যা নির্ধারণ করে যে কোনও সংগ্রহের সমস্ত মান অন্যটিতে অন্তর্ভুক্ত রয়েছে কিনা। আপনার যদি কেবল IEnumerable<T>বিপরীতে কাজ করতে হয় তবে আমি ব্যবহার করব Intersect

var allOfList1IsInList2 = list1.Intersect(list2).Count() == list1.Count();

এটির কার্য সম্পাদন খুব যুক্তিসঙ্গত হওয়া উচিত, যেহেতু Intersect()প্রতিটি তালিকার উপরে একবারে গণনা করা হবে। এছাড়াও, Count()অন্তর্নিহিত প্রকারটি যদি কেবল একটি ICollection<T>না হয়ে থাকে তবে দ্বিতীয় কলটি সর্বোত্তম হবে IEnumerable<T>


আমি কিছু পরীক্ষা করেছি এবং এই পদ্ধতিটি অন্যদের চেয়ে দ্রুত চলমান বলে মনে হচ্ছে। বখশিশের জন্য ধন্যবাদ.
ব্র্যান্ডন জ্যাকারি

2
তালিকায় নকল থাকলে এটি কাজ করে না। উদাহরণস্বরূপ 441 এবং 414 এর সাথে চারটির অ্যারের তুলনা করলে 41 রিটার্ন হয় এবং সুতরাং গণনা ব্যর্থ হয়।
জন

69

আপনি প্রথম তালিকা থেকে দ্বিতীয় তালিকায় বিদ্যমান সমস্ত মান মুছে ফেলা ছাড়াও ব্যবহার করতে পারেন, এবং তারপরে সমস্ত মান মুছে ফেলা হয়েছে কিনা তা পরীক্ষা করে দেখুন:

var allOfList1IsInList2 = !list1.Except(list2).Any();

এই পদ্ধতিতে কাউন্ট () এ দুটি কল না করার সুবিধা ছিল।


তালিকা 1-এ কী আছে তবে তালিকার 2-তে কী তা খুঁজে বের করার জন্য এটি ভাল;
হোমার

16
এটি এমন পরিস্থিতিতে কাজ করে যেখানে তালিকার 1 নকল মান রয়েছে। গৃহীত উত্তর দেয় না।
ডিবিসি

23

সি # 3.5+

Enumerable.All<TSource>সমস্ত তালিকা 2 আইটেম তালিকা 1 এ অন্তর্ভুক্ত রয়েছে কিনা তা নির্ধারণ করতে ব্যবহার করে :

bool hasAll = list2Uris.All(itm2 => list1Uris.Contains(itm2));

তালিকা 1 এর তালিকায় থাকা সমস্ত আইটেমের চেয়েও বেশি থাকে তখন এটি কাজ করবে।


10
একটি Contains()কল মধ্যে কল এর কার্যকারিতা প্রভাব All()
কেন্ট বুগার্ট

এছাড়াও আপনি এটিকে গ্রুপ পদ্ধতিতে স্থানান্তরিত করতে পারেন: bool hasAll = list2Uris.All (list1Uris.Contains);
জিম্পাঞ্জার

আমি অনুমানযোগ্য <টি> প্রকারের ক্ষেত্রে এই সমাধানটি এন * মি কার্যকারিতা সরবরাহ করবে।
দিমিত্রি দোকসিন

4
শর্টহ্যান্ড: bool hasAll = list2Uris.All(list1Uris.Contains);
আলোকসজ্জা

3

কেন্টের উত্তর উত্তম এবং সংক্ষিপ্ত, তবে তিনি যে সমাধানটি সরবরাহ করেন তা সর্বদা পুরো প্রথম সংগ্রহের মাধ্যমে পুনরাবৃত্তি প্রয়োজন। উত্স কোডটি এখানে:

public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
    if (first == null)
        throw Error.ArgumentNull("first");
    if (second == null)
        throw Error.ArgumentNull("second");
    return Enumerable.IntersectIterator<TSource>(first, second, comparer);
}

private static IEnumerable<TSource> IntersectIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
    Set<TSource> set = new Set<TSource>(comparer);
    foreach (TSource source in second)
        set.Add(source);
    foreach (TSource source in first)
    {
        if (set.Remove(source))
            yield return source;
    }
}

এটি সর্বদা প্রয়োজন হয় না। সুতরাং, এখানে আমার সমাধান:

public static bool Contains<T>(this IEnumerable<T> source, IEnumerable<T> subset, IEqualityComparer<T> comparer)
{
    var hashSet = new HashSet<T>(subset, comparer);
    if (hashSet.Count == 0)
    {
        return true;
    }

    foreach (var item in source)
    {
        hashSet.Remove(item);
        if (hashSet.Count == 0)
        {
            break;
        }
    }

    return hashSet.Count == 0;
}

আসলে, আপনি ISet<T>( HashSet<T>) ব্যবহার সম্পর্কে চিন্তা করা উচিত । এটিতে প্রয়োজনীয় সমস্ত সেট পদ্ধতি রয়েছে। IsSubsetOfতোমার ক্ষেত্রে.


2

লিনক অপারেটর সিকোয়েন্সএকুয়াল এছাড়াও কাজ করবে (তবে গণ্যকারীর আইটেম একই ক্রমে সংবেদনশীল)

return list1Uris.SequenceEqual(list2Uris);

2

উত্তর হিসাবে চিহ্নিত সমাধান পুনরাবৃত্তির ক্ষেত্রে ব্যর্থ হবে। যদি আপনার আইনামেবলে কেবলমাত্র স্বতন্ত্র মান থাকে তবে তা পাস হয়ে যাবে।

নীচের উত্তরটি পুনরাবৃত্তি সহ 2 টি তালিকার জন্য:

        int aCount = a.Distinct().Count();
        int bCount = b.Distinct().Count();

        return aCount == bCount &&
               a.Intersect(b).Count() == aCount;

এটি সমস্ত সদৃশ অপসারণ এবং বাস্তবে সেগুলির তুলনা না করায় এটি কোনও ভাল সমাধান নয়।
জন

2

আপনার অ্যারের পরিবর্তে হ্যাশসেট ব্যবহার করা উচিত।

উদাহরণ:

List1.SetEquals(List2); //returns true if the collections contains exactly same elements no matter the order they appear in the collection

উল্লেখ

কেবলমাত্র হ্যাসসেটের সীমাবদ্ধতা হ'ল আমরা সূচির মতো সূচী দ্বারা আইটেমটি পেতে পারি না বা অভিধানের মতো কী দ্বারা আইটেমটি পেতে পারি না। আপনি যা করতে পারেন তা হ'ল তাদের প্রত্যেককে গণনা করা হবে (প্রত্যেকের জন্য, অন্যদিকে)

যদি এটি আপনার পক্ষে কাজ করে তবে দয়া করে আমাকে জানান


-2

আপনি দুটি তালিকার তুলনা করতে এই পদ্ধতিটি ব্যবহার করতে পারেন

    //Method to compare two list
    private bool Contains(IEnumerable<Item> list1, IEnumerable<Item> list2)
    {
        bool result;

        //Get the value
        var list1WithValue = list1.Select(s => s.Value).ToList();
        var list2WithValue = list2.Select(s => s.Value).ToList();

        result = !list1WithValue.Except(list2WithValue).Any();

        return result;
    }

: প্রায় কাছাকাছি একই উত্তর 3 বছর আগে দেওয়া হয়েছিল stackoverflow.com/a/16967827/5282087
Dragomok
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.