كيف أقوم بإجراء FindAll() على Ilist<T>؟(على سبيل المثال.القائمة المصنفة. القيم)

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

  •  03-07-2019
  •  | 
  •  

سؤال

أنا أعمل على حل مشكلة في C# 2.0/.NET 2.0 حيث لدي قائمة مصنفة وأريد البحث في جميع "القيم" (وليس "المفاتيح") لهذه القائمة المصنفة عن سلسلة فرعية معينة وإحصاء عدد التكرارات الموجودة .

هذا ما أحاول القيام به:

{
   Sortedlist<string,string> mySortedList;
   // some code that instantiates mySortedList and populates it with data
   List<string> myValues = mySortedList.Values;  // <== does not work
   int namesFound = myValues.FindAll(ByName(someName)).Count;
}

وبطبيعة الحال، لا يعمل هذا لأن mySortedList.Values ​​يُرجع قائمة IList، في حين أن "myValues" عبارة عن قائمة.لقد حاولت "إرسال" قائمة IList بحيث يتم قبولها بواسطة myValues، لكن يبدو أن الأمر لا يعمل.

بالطبع، يمكنني تكرار mySortedList.Values ​​في حلقة "foreach"، لكنني لا أريد حقًا القيام بذلك.

هل لديكم أي اقتراحات؟

تحرير-1:حسنًا، يبدو أنه لا توجد طريقة أصلية للقيام بذلك بسهولة.لقد افترضت أنني كنت أفتقد شيئًا ما، لكن من الواضح أنني لست كذلك.لذا أعتقد أنني سأقوم فقط بإجراء "بحث" على قائمة IList.

شكرا لتعليقات الجميع!لقد صوتت للجميع لصالح 1 لأنني اعتقدت أن جميع التعليقات كانت جيدة.شكرًا لك مرة أخرى!:-)

تحرير-2:يبدو أن نظام إدارة المحتوى (CMS) لديه الإجابة التي كنت أبحث عنها.التحذير الوحيد في هذا (كما أشار Qwertie) هو أن هناك عقوبة أداء محتملة نظرًا لأنه يتضمن نسخ جميع القيم إلى قائمة أخرى ثم البحث في تلك القائمة من البداية إلى النهاية.لذلك بالنسبة للقوائم القصيرة، هذه الإجابة فعالة.قوائم أطول؟حسنًا ، الأمر متروك لك لتقرر ...

هل كانت مفيدة؟

المحلول

منذ واجهة إليست ينفذ لا يحصى, ، يمكنك في الواقع الحصول على List<T> من القيم باستخدام List<T> (IEnumerable) Constructor:

List<string> myValues = new List<string>(mySortedList.Values);

نصائح أخرى

لا يمكنك تحويل خاصية القيم إلى قائمة <سلسلة> لأنها ليست قائمة <سلسلة>--بل هي قاموس <TKey, TValue>.ValueCollection.

ولكن إذا كنت تستخدم LinqBridge (بالنسبة لـ .NET Framework 2.0 مع C# 3.0)، يتم حل هذه المشكلة بسهولة باستخدام LINQ كما يلي:

SortedList<string, string> m = ...;
int namesFound = m.Values.Where(v => v.Contains("substring")).Count();

(إذا كنت لا تزال تستخدم الإصدار 2.0 من C#، فيمكنك استخدام لينك الرجل الفقير بدلاً من ذلك، مع المزيد من العمل قليلاً)

من المؤسف أنك تستخدم .Net 2.0.هذا هو بالضبط الغرض من LINQ.;)

لا يمكنك فعل هذا حقًا، نظرًا لأن FindAll() عضو في القائمة.يمكنك إنشاء قائمة جديدة في mySortedList.Values، ولكن يبدو أن هذا مضيعة، حيث يجب تخصيص كائن جديد ومصفوفة أساسية فقط لاستدعاء دالة.

سأكتب فقط وظيفة مساعدة في بعض الفئات لقوائم تسمى FindAll () ثم قم بتمرير IList الخاص بك والمفوض.

هل جربت SortedListGetValueList حتى الآن؟هذا سوف يعطيك مرة أخرى IList من القيم.

    static void Main(string[] args)
    {
        string someName = "two";
        SortedList<string, string> mySortedList = new SortedList<string,string>()
        {
            {"key1", "This is key one"},
            {"key2", "This is key two"},
            {"key3", "This is key three"},
        };

        int namesFound = mySortedList.Values.Where(i => i.Contains(someName)).Count();
        Console.WriteLine(namesFound);
        Console.ReadKey();
    }

في Framework 2.0، ربما يمكنك القيام بذلك:

    static void Main(string[] args)
    {
        string someName = "two";
        SortedList<string, string> mySortedList = new SortedList<string,string>()
        {
            {"key1", "This is key one"},
            {"key2", "This is key two"},
            {"key3", "This is key three"},
        };

        int namesFound = FindAll(mySortedList.Values, someName).Count ;
        Console.WriteLine(namesFound);
        Console.ReadKey();
    }
    public static IList<String> FindAll(IList<String> items, string item)
    {
        List<String> result = new List<string>();
        foreach (String s in items)
        {
            if (s.Contains(item))
            {
                result.Add(s);
            }
        }
        return result;
    }

ولكن هذا ما كنت حقا لا تريد أن تفعل.

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