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

本文关键字:最佳 方法 列表 修改 循环 | 更新日期: 2023-09-27 18:07:16

我很好奇在c#中修改列表的最好方法是什么。据我所知,foreach循环用于遍历列表以获取所需的信息,如果需要修改列表,则使用for循环。我发现了3种修改列表的方法,但它们似乎都像预期的那样删除了大部分项目。

我的问题是:

1)下面所示的这三种方式有什么区别?

2)是否有一个特定的时间,其中一个应该使用另一种方式?

3)有没有其他更好的方法来修改列表?

4)当删除你意味着颠倒列表时,这仅仅是为了不打乱顺序并引起不可预测的副作用吗?

反向for循环:

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

创建列表的副本

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

反向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");
    }
}

有几件事让我很困惑,我想澄清一下。

提前感谢。

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

逐个删除条目似乎是效率最低的方法(接近于二次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)

同时移除.RemoveAll.RemoveRange的所有项为O(n)

这里的答案似乎是最有效的,因为它只是移动项目而不删除它们,然后在最后删除额外的项目:

根据条件从List<T>中删除项的最佳方法是使用RemoveAll方法,该方法内部针对此类操作进行了优化:

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

用LINQ来做,它只会遍历一次列表,非常高效。

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

如果您需要对给定的列表进行进一步操作,则执行(即使它创建了一个带有引用的新列表):

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

的问候

康斯坦丁