【问题标题】:How to iterate through a list that is being modified?如何遍历正在修改的列表?
【发布时间】:2010-11-13 11:21:09
【问题描述】:

我有一个数据集中的行列表,我需要遍历这些行。

问题在于迭代中的处理可能会从列表中删除一行或多行。

由于列表正在修改,我不能使用 foreach() 循环。

但是由于在我正在处理的元素之前可能会发生一些删除,所以我也不能使用 for() 循环(即,如果我正在处理 element ,这会导致删除元素和其他元素,我想不出一种方法来调整 i 以正确指向我正在处理的元素之后的元素)。

您将如何解决这个问题?我目前的想法是始终处理列表中的第一个元素。如果它被删除,则处理新的第一个元素。如果它没有被删除,则将其移动到“alreadyProcessed”列表,并处理新的第一个元素。

有没有更简单的方法?

【问题讨论】:

    标签: c# list iteration


    【解决方案1】:

    如果你能把你的数据放到一个链表中,那你就是黄金。

    【讨论】:

      【解决方案2】:
      
      
      int i = 0;
      while (i < dataSet.Tables[0].Rows.Count) {
          if (some_condition) {
             dataSet.Tables[0].Rows.RemoveAt(i);
             continue;
          }
          i++;
      }
      

      【讨论】:

      • 如果发生多个删除(我不容易知道的情况),那么 i(或 i++)将不会指向正确的下一个元素。 (可能会发生多个删除的原因是由于在一对多关系中级联删除。)
      • 是的,如果您删除(而不是删除)一行。但是我的示例从 DataTable 中删除了行。如果您使用 Delete(),您可以检查循环中每一行的 RowState == RowState.Deleted。
      【解决方案3】:

      在修改我正在迭代的列表时,我总是发现用我想要保留的项目构建一个新列表最容易,然后使用新列表来做我想做的任何事情。

      我想这真的取决于你完成后对数据的处理方式。

      【讨论】:

      • 这就是我倾向于的方向。感谢您的确认。
      【解决方案4】:
      for(int i = list.Length -1, i >= 0; i--)
      {
         // process and delete if you want
      }
      

      【讨论】:

      • 见我上面对大卫的评论。
      【解决方案5】:

      通常这是通过反向循环完成的:

      List<string> Items = ...
      for(int i = Items.Count - 1; i >= 0; i--)
      {
         if(Items[i] == "DELETE ME")
         {
            Items.RemoveAt(i);
         }
      }
      

      这会导致项目以相反的顺序处理,因此如果您删除一个项目,它不会影响任何仍待处理的项目的位置。

      【讨论】:

      • 这在我正在考虑的情况下不起作用,因为删除可能不仅发生在元素 i 上,还发生在其他元素 i+/-n 上,这意味着 i-- 可能或者可能没有指向正确的下一个元素。此外,删除多个元素可能会使 i 甚至 i-- 指向列表末尾之外不再存在的对象。 (另请注意,我不一定知道有多少元素可能已被删除。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-16
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      相关资源
      最近更新 更多