تعديل المجموعة عند استخدام حلقة Foreach في C # [مكررة

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

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

في الأساس، أود إزالة عنصر من قائمة أثناء وجوده داخل حلقة Foreach. أعلم أن هذا ممكن عند استخدام A للحلقة، ولكن لأغراض أخرى، أود أن أعرف ما إذا كان هذا ممكنا باستخدام حلقة Foreach.

في بيثون يمكننا تحقيق ذلك من خلال القيام بما يلي:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

for i in a:
    print i

    if i == 1:
        a.pop(1)

هذا يعطي الناتج التالي

>>>1
3
4
5
6
7
8
9

ولكن عند القيام بشيء مماثل في C #، أحصل على InvalistoperationException، كنت أتساءل عما إذا كانت هناك طريقة للتجول في هذا الأمر، دون ببساطة باستخدام a لحلقة.

الرمز في C # الذي استخدمته عند طرح الاستثناء:

static void Main(string[] args)
  {
  List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9"});

  foreach (string Item in MyList)
    {
    if (MyList.IndexOf(Item) == 0)
      {
      MyList.RemoveAt(1);
      }

    Console.WriteLine(Item);
    }
  }

شكرا مقدما

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

المحلول

لا يمكنك القيام بذلك. من مستندات IEnumerator<T>:

لا يزال العداد ساري المفعول طالما بقيت المجموعة دون تغيير. إذا تم إجراء التغييرات على المجموعة، مثل إضافة أو تعديل أو حذف العناصر، فإن العداد غير قابل للإلغاء بشكل لا يصدق وسلوكه غير محدد.

البدائل هي:

  • قم ببناء قائمة جديدة من العناصر لإزالتها، ثم قم بإزالتها جميعها بعد ذلك
  • استخدم حلقة "ل" طبيعية "وتأكد من أنك حريص على عدم الذهاب فوق نفس العنصر مرتين أو مفقود. (قلت أنك لا ترغب في القيام بذلك، ولكن ما تحاول القيام به فقط لن يعمل.)
  • بناء مجموعة جديدة تحتوي فقط على العناصر التي تريد الاحتفاظ بها

آخر هذه البدائل هو الحل الذي يشبه LINQ، حيث تكتب عادة:

var newList = oldList.Where(x => ShouldBeRetained(x)).ToList();

(أين ShouldBeRetained هو مهما كان المنطق الذي تريده، بالطبع.) الدعوة إلى ToList() ضروري فقط إذا كنت ترغب في الواقع في قائمة. يؤدي هذا إلى مزيد من التعليمات البرلانية التي غالبا ما تكون أسهل في القراءة. لا أستطيع بسهولة تخمين ما يقصد به حلقةك الأصلية القيام به (يبدو غريبا في الوقت الحالي) في حين يمكنك التعبير عن المنطق بحتة من حيث العنصر، فقد يكون الأمر أكثر وضوحا.

نصائح أخرى

إذا كان كل ما تحتاجه هو إزالة جميع العناصر التي تلبي الشرط الذي يمكنك استخدامه قائمةu003CT> .حذف الكل طريقة:

List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9" });
MyList.RemoveAll(item => item == "1");

لاحظ أن هذا يعدل القائمة الأولية.

أنت بالتأكيد قد لا تغير مجموعة بأي طريقة عند استخدام حلقة foreach عليها.

يمكنك استخدام A LOOP وإدارة الفهرس بنفسك أو إنشاء نسخة من المجموعة وأنت تحلق الأصل، وإزالة العناصر من النسخة التي تساوي العنصر في الأصل.

في كلتا الحالتين أنها ليست واضحة أو مريحة :).

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