كيفية تعديل أو حذف عناصر من مجموعة enumerable بينما بالتكرار من خلال ذلك في C #

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

  •  08-07-2019
  •  | 
  •  

سؤال

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

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

المحلول

ويمكنك إزالة عناصر من مجموعة إذا كنت تستخدم for حلقة بسيطة.

ونلقي نظرة على هذا المثال:

        var l = new List<int>();

        l.Add(0);
        l.Add(1);
        l.Add(2);
        l.Add(3);
        l.Add(4);
        l.Add(5);
        l.Add(6);

        for (int i = 0; i < l.Count; i++)
        {
            if (l[i] % 2 == 0)
            {
                l.RemoveAt(i);
                i--;
            }
        }

        foreach (var i in l)
        {
            Console.WriteLine(i);
        }

نصائح أخرى

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

        List<int> test = new List<int>();
        test.Add(1);
        test.Add(2);
        test.Add(3);
        test.Add(4);
        test.Add(5);
        test.Add(6);
        test.Add(7);
        test.Add(8);
        for (int i = test.Count-1; i > -1; i--)
        {
            if(someCondition){
                test.RemoveAt(i);
            }
        }

وأخذbruno رمز، وأنا سوف نفعل ذلك الى الوراء.

ولأن عند الانتقال إلى الوراء، مؤشرات مجموعة المفقودة لا تتداخل مع ترتيب حلقة الخاص بك.

var l = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6 });

for (int i = l.Count - 1; i >= 0; i--)
    if (l[i] % 2 == 0)
        l.RemoveAt(i);

foreach (var i in l)
{
    Console.WriteLine(i);
}

ولكن seriuosly، في هذه الأيام، فما استقاموا لكم فاستقيموا استخدام LINQ:

var l = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6 });

l.RemoveAll(n => n % 2 == 0);

ومنذ كنت تعمل مع DataTable ووتحتاج إلى أن تكون قادرة على الاستمرار أية تغييرات مرة أخرى إلى الخادم مع محول الجدول (انظر تعليق)، وهنا مثال على كيف يجب أن حذف الصفوف:

DataTable dt;
// remove all rows where the last name starts with "B"
foreach (DataRow row in dt.Rows)
{
    if (row["LASTNAME"].ToString().StartsWith("B"))
    {
        // mark the row for deletion:
        row.Delete();
    }
}

ودعوة حذف على الصفوف وتغيير الخاصية RowState لمحذوفة، ولكن ترك الصفوف المحذوفة في الجدول. إذا كنت لا تزال بحاجة للعمل مع هذا الجدول قبل استمرار التغييرات مرة أخرى إلى الخادم (مثل إذا كنت ترغب في عرض محتويات الجدول ناقص الصفوف المحذوفة)، تحتاج إلى التحقق من RowState من كل صف كما كنت بالتكرار من خلال مثل هذا :

foreach (DataRow row in dt.Rows)
{
    if (row.RowState != DataRowState.Deleted)
    {
        // this row has not been deleted - go ahead and show it
    }
}

وإزالة الصفوف من جمع (كما في الجواب برونو) وكسر محول الجدول، ويجب عموما لا ينبغي القيام به مع DataTable و.

وحين حلقة من شأنه أن التعامل مع هذا:

int i = 0;
while(i < list.Count)
{
    if(<codition for removing element met>)
    {
        list.RemoveAt(i);
    }
    else
    {
        i++;
    }
}
ويمكن أيضا

وحل chakrit في استخدامها إذا كنت تستهدف .NET Framework 2.0 (أي تعبيرات LINQ / امدا) باستخدام مندوب بدلا من التعبير امدا:

public bool IsMatch(int item) {
    return (item % 3 == 1); // put whatever condition you want here
}
public void RemoveMatching() {
    List<int> x = new List<int>();
    x.RemoveAll(new Predicate<int>(IsMatch));
}

وحذف أو إضافة إلى قائمة بينما بالتكرار من خلال ذلك يمكن كسرها، كما قلت لك.

وأنا غالبا ما تستخدم نهج اثنين القائمة على حل المشكلة:

ArrayList matches = new ArrayList();   //second list

for MyObject obj in my_list
{

    if (obj.property == value_i_care_about)
        matches.addLast(obj);
}

//now modify

for MyObject m in matches
{
    my_list.remove(m); //use second list to delete from first list
}

//finished.

وعندما تحتاج إلى إزالة عنصر من مجموعة أنني تعداد أنا عادة تعداد في الاتجاه المعاكس.

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