迭代列表并从中删除项目的最佳方法是什么?

Avi*_*atz 16 c# iteration list

我需要迭代List<myObject>并删除回答某个条件的项目.

我看到了这个答案(/sf/answers/110762221/):

使用for循环反向迭代列表:

for (int i = safePendingList.Count - 1; i >= 0; i--)
{
    // some code
    // safePendingList.RemoveAt(i);
}
Run Code Online (Sandbox Code Playgroud)

例:

var list = new List<int>(Enumerable.Range(1, 10));
for (int i = list.Count - 1; i >= 0; i--)
{
    if (list[i] > 5)
      list.RemoveAt(i);
}
list.ForEach(i => Console.WriteLine(i));
Run Code Online (Sandbox Code Playgroud)

但我明白,for比效率较低foreach,

所以我想用后面的如下:

foreach (var item in myList.ToList())
{
    // if certain condition applies:
    myList.Remove(item)
}
Run Code Online (Sandbox Code Playgroud)

一种方法比另一种更好吗?

编辑:

我不想使用RemoveAll(...),因为在条件之前循环中有大量代码.

Dmi*_*nko 21

Willy-nilly你必须循环遍历列表,for循环是最有效的循环:

  for (int i = safePendingList.Count - 1; i >= 0; --i) 
    if (condition)
      safePendingList.RemoveAt(i);
Run Code Online (Sandbox Code Playgroud)

如果要删除范围(不在整个列表中),只需修改for循环:

  // No Enumarable.Range(1, 10) - put them into "for"
  for (int i = Math.Min(11, safePendingList.Count - 1); i >= 1; --i)
    if (condition)
      safePendingList.RemoveAt(i); 
Run Code Online (Sandbox Code Playgroud)

或者,如果您必须删除正向循环中的项目:

  for (int i = 0; i < safePendingList.Count;) // notice ++i abscence
    if (condition)
      safePendingList.RemoveAt(i);
    else
      i += 1; // ++i should be here
Run Code Online (Sandbox Code Playgroud)

相反,safePendingList.ToList()创建一个初始副本,safePendingList这意味着内存CPU 开销:

  // safePendingList.ToList() - CPU and Memory overhead (copying)
  foreach (var item in safePendingList.ToList()) {
    if (condition)
      myList.Remove(item); // Overhead: searching
  }
Run Code Online (Sandbox Code Playgroud)

但是,在许多情况下,最合理的计划只是让.Net为您工作:

  safePendingList.RemoveAll(item => condition);
Run Code Online (Sandbox Code Playgroud)

  • `safePendingList.RemoveAll(item => condition);`最接近高阶`filter`y函数 (3认同)
  • 除了简短易读之外,"RemoveAll"还有一个主要的好处,它需要线性时间,无论需要移除多少或哪些项目.由于需要重复移动列表的大部分,基于"RemoveAt"的解决方案可能需要二次时间. (2认同)

fub*_*ubo 7

删除您可以使用的具有特定条件的项目

list.RemoveAll(item => item > 5);
Run Code Online (Sandbox Code Playgroud)

代替

var list = new List<int>(Enumerable.Range(1, 10));
for (int i = list.Count - 1; i >= 0; i--)
{
    if (list[i] > 5)
        list.RemoveAt(i);
}
Run Code Online (Sandbox Code Playgroud)