当前位置:  开发笔记 > 编程语言 > 正文

如何在C#中迭代可枚举集合中的项目时修改或删除它们

如何解决《如何在C#中迭代可枚举集合中的项目时修改或删除它们》经验,为你挑选了4个好方法。

我必须从数据表中删除一些行.我听说在迭代它时改变一个集合是不行的.因此,我不是检查一行是否满足删除要求然后将其标记为已删除的for循环,而应首先遍历数据表并在列表中添加所有行,然后遍历列表并标记删除行.这是什么原因,我有什么替代品(而不是使用我的意思的行列表)?



1> Michael Stum..:

迭代后退通过列表听起来像一个更好的方法,因为如果你删除一个元素和其他元素"落入差距",这没关系,因为你已经看过那些.此外,您不必担心您的计数器变量变得大于.Count.

        List test = new List();
        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);
            }
        }



2> chakrit..:

拿@bruno代码,我会倒退.

因为当您向后移动时,缺少的数组索引不会干扰循环的顺序.

var l = new List(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);
}

但是,如今,我会使用LINQ:

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

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


+1用于实现LINQ的强大功能.为什么事情在你不必要的时候还有很长的路要走
RemoveAll + 1.注意RemoveAll不是严格的LINQ.它适用于没有LINQ支持的.NET 2.0中的任何"List"类.
@sebastion我认为你误解了"var"是如何工作的.

3> bruno conde..:

如果使用简单for循环,则可以从集合中删除元素.

看看这个例子:

        var l = new List();

        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);
        }


迭代*向后*会不会更好?for(int i = l.count; i> 0; i--).这样,如果你删除一个元素并且下一个元素"落入它的位置",那就无所谓了,因为你已经检查过了.或者我在这里遗漏了什么?
最好使用内置的RemoveAll方法,该方法将谓词作为参数.
这是有缺陷的,因为不会检查所有元素.如果你在i处删除了一个元素,那么i + 1处的元素就变成了i.当我为下一个循环递增时,它将跳过刚刚替换被删除元素的元素(希望这是有意义的).

4> MusiGenesis..:

由于您正在使用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();
    }
}

在行上调用delete会将其RowState属性更改为Deleted,但会将已删除的行保留在表中.如果在将更改保存到服务器之前仍然需要使用此表(如果要显示表的内容减去已删除的行),则需要在迭代时检查每行的RowState,如下所示:

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

从集合中删除行(如bruno的答案)将破坏表适配器,通常不应该使用DataTable.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有