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

时间:2016-09-15 11:59:28

标签: c# list for-loop foreach

我很好奇在c#中修改列表的最佳方法是什么。据我所知,foreach循环用于迭代列表以获取所需信息,如果需要修改列表,则使用for循环。我找到了3种修改列表的方法,但它们似乎都按照预期删除了这些项目。

所以我的问题是:

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

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

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

4)当你删除你的意思是颠倒这个清单时,这只是为了不扰乱秩序并造成不可预测的副作用吗?

反向循环:

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

只有一些让我感到困惑并想要清理的事情。

提前谢谢。

3 个答案:

答案 0 :(得分:2)

逐个删除项目似乎是效率最低的方式(更接近二次O(n²)complexity),但是新列表更接近线性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)

这里的答案看起来效率最高,因为它只移动项目而不删除它们,然后删除最后的额外项目:Removing alternate elements in a List<T>

答案 1 :(得分:1)

根据条件从List<T>中删除项目的最佳方法是使用内部RemoveAlloptimized方法进行此类操作:

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

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

答案 2 :(得分:0)

使用LINQ进行操作,只需在列表中执行一次非常高效的操作。

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

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

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

问候

康斯坦丁