أنظف طريقة للعثور على تطابق في القائمة

StackOverflow https://stackoverflow.com/questions/23787

  •  09-06-2019
  •  | 
  •  

سؤال

ما هي أفضل طريقة للعثور على شيء ما في القائمة؟أعلم أن LINQ لديه بعض الحيل الرائعة، ولكن دعنا نحصل أيضًا على اقتراحات لـ C# 2.0.لنحصل على أفضل عمليات إعادة البناء لنمط الكود الشائع هذا.

حاليًا أستخدم رمزًا مثل هذا:

// mObjList is a List<MyObject>
MyObject match = null;
foreach (MyObject mo in mObjList)
{
    if (Criteria(mo))
    {
        match = mo;
        break;
    }
}

أو

// mObjList is a List<MyObject>
bool foundIt = false;
foreach (MyObject mo in mObjList)
{
    if (Criteria(mo))
    {
        foundIt = true;
        break;
    }
}
هل كانت مفيدة؟

المحلول

@ كونراد:إذا كيف يمكنك أن تستفيد منها؟لنفترض أنني أريد مطابقة mo.ID مع الرقم السحري.

في C# 2.0 ستكتب:

result = mObjList.Find(delegate(int x) { return x.ID == magicNumber; });

3.0 يعرف لامدا:

result = mObjList.Find(x => x.ID == magicNumber);

نصائح أخرى

باستخدام تعبير لامدا:

List<MyObject> list = new List<MyObject>();

// populate the list with objects..

return list.Find(o => o.Id == myCriteria);

ضع الكود في طريقة وتقوم بحفظ مؤقت و break (ويمكنك إعادة تدوير الكود كمكافأة):

T Find<T>(IEnumerable<T> items, Predicate<T> p) {
    foreach (T item in items)
        if (p(item))
            return item;

    return null;
}

… ولكن بالطبع هذه الطريقة موجودة بالفعل على أية حال بالنسبة للقوائم، حتى في .NET 2.0.

من الواضح أن أداء المندوبين المجهولين يعد مهمًا جدًا.

رمز الاختبار:

    static void Main(string[] args)
    {
        for (int kk = 0; kk < 10; kk++)
        {
            List<int> tmp = new List<int>();
            for (int i = 0; i < 100; i++)
                tmp.Add(i);
            int sum = 0;
            long start = DateTime.Now.Ticks;
            for (int i = 0; i < 1000000; i++)
                sum += tmp.Find(delegate(int x) { return x == 3; });
            Console.WriteLine("Anonymous delegates: " + (DateTime.Now.Ticks - start));


            start = DateTime.Now.Ticks;
            sum = 0;
            for (int i = 0; i < 1000000; i++)
            {
                int match = 0;
                for (int j = 0; j < tmp.Count; j++)
                {
                    if (tmp[j] == 3)
                    {
                        match = tmp[j];
                        break;
                    }
                }
                sum += match;
            }
            Console.WriteLine("Classic C++ Style: " + (DateTime.Now.Ticks - start));
            Console.WriteLine();
        }
    }

نتائج:

Anonymous delegates: 710000
Classic C++ Style: 340000

Anonymous delegates: 630000
Classic C++ Style: 320000

Anonymous delegates: 630000
Classic C++ Style: 330000

Anonymous delegates: 630000
Classic C++ Style: 320000

Anonymous delegates: 610000
Classic C++ Style: 340000

Anonymous delegates: 630000
Classic C++ Style: 330000

Anonymous delegates: 650000
Classic C++ Style: 330000

Anonymous delegates: 620000
Classic C++ Style: 330000

Anonymous delegates: 620000
Classic C++ Style: 340000

Anonymous delegates: 620000
Classic C++ Style: 400000

في كل حالة، يكون استخدام المفوضين المجهولين أبطأ بنسبة 100% تقريبًا من الطريقة الأخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top