简体   繁体   English

在循环C#中修改列表的最佳方法

[英]Best way to modify a list in a loop C#

I am curious as to what is the best way to modify a list in c#. 我很好奇在c#中修改列表的最佳方法是什么。 As far as I'm aware, the foreach loop is used to iterate over the list to get the desired information and if you need to modify the list then use a for loop. 据我所知,foreach循环用于遍历列表以获取所需的信息,如果您需要修改列表,请使用for循环。 I have found 3 ways to modify a list but they all seem to pretty much remove the items as intended. 我发现了三种修改列表的方法,但它们似乎都可以按预期删除项目。

So my questions are: 所以我的问题是:

1) What is the difference between these 3 ways shown below? 1)如下所示的这三种方式有什么区别?

2) is there a specific time where one of them should be used over the other way? 2)是否有特定时间使用其中一种方法?

3) Is there any other better ways to modify a list? 3)还有其他更好的方法来修改列表吗?

4) When removing you are meant to reverse the list, is this simply to not mess up the order and cause unpredictable side effects? 4)当删除您是要反转列表时,这是否只是为了不弄乱顺序并引起不可预测的副作用?

Reverse for loop: 反向循环:

List<int> integerListForReverse = new List<int>();
for(int i = 0; i <10; i ++)
{
    integerListForReverse.Add(i);
}

for (int i = integerListForReverse.Count - 1; i >= 0; i--)
{
    int ints = i;
    if(ints % 2 == 0)
    {
        integerListForReverse.Remove(ints);
        Console.WriteLine(ints + " reverse for loop");
    }
}

Create a copy of the list 创建列表的副本

List<int> integerListForeachCopy = new List<int>();
for (int i = 0; i < 10; i++)
{
    integerListForeachCopy.Add(i);
}

foreach (int ints in integerListForeachCopy.ToList())
{
    if (ints % 2 == 0)
    {
        integerListForeachCopy.Remove(ints);
        Console.WriteLine(ints + "copy of the list ");
    }
}

Reverse foreach loop 反向foreach循环

List<int> integerListReverseForeach = new List<int>();
for (int i = 0; i < 10; i++)
{
    integerListReverseForeach.Add(i);
}
foreach (int ints in integerListReverseForeach.Reverse<int>())
{
    if (ints % 2 == 0)
    {
        integerListReverseForeach.Remove(ints);
        Console.WriteLine(ints + "reverse foreach");
    }
}

Just a few things that were confusing me and would like cleared up. 只是让我感到困惑并且想清除的几件事。

Thank you in advance. 先感谢您。

Removing the items one by one seems like the least efficient way ( closer to quadratic O(n²) complexity ), but making a new list is closer to linear O(n) complexity: 逐个删除项目似乎是效率最低的方法(接近二次O(n²) 复杂度 ),但是制作新列表更接近线性O(n)复杂度:

var L = Enumerable.Range(0, 10).ToList();

L = L.Where(i => (i & 1) > 0).ToList();
//L = Enumerable.Range(0, L.Count / 2).Select(i => L[(i << 1) + 1]).ToList(); 
//L = Enumerable.Range(0, L.Count).Where(i => (i & 1) > 0).Select(i => L[i]).ToList();
//L.RemoveAll(i => (i & 1) == 0); // { 1, 3, 5, 7, 9 } // O(n)

Removing all items at once with .RemoveAll and .RemoveRange is O(n) 使用.RemoveAll.RemoveRange一次删除所有项目为O(n)

The answer here seems like the most efficient as it just moves the items without removing them, and then removes the extra items at the end: Removing alternate elements in a List<T> 答案似乎是最有效的,因为它只是移动项目而不删除它们,然后最后删除多余的项目: 删除List <T>中的备用元素

The best way for removing items from a List<T> based on condition is using the RemoveAll method which is internally optimized for such operation: 根据条件从List<T>删除项目的最佳方法是使用为该操作进行内部优化RemoveAll方法:

var list = new List<int>();
for(int i = 0; i <10; i ++)
    list.Add(i);

list.RemoveAll(value => (value % 2) == 0);

Do it with LINQ, which will just go once through the list being very efficient. 使用LINQ可以做到这一点,因为它非常有效。

var result = list.Where(x => (x % 2) != 0);

if you need to operate further on the given list, do (even tho it creates a new List with references): 如果您需要在给定列表上进行进一步的操作,请执行以下操作(甚至通过引用创建新列表):

list = list.Where(x => (x % 2) != 0).ToList();

Greetings 问候

Konstantin 康斯坦丁

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM