Anonymous5642
Anonymous5642

Reputation: 25

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#. 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. 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?

2) is there a specific time where one of them should be used over the other way?

3) Is there any other better ways to modify a list?

4) When removing you are meant to reverse the list, is this simply to not mess up the order and cause unpredictable side effects?

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

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.

Upvotes: 0

Views: 996

Answers (3)

Slai
Slai

Reputation: 22866

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:

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)

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>

Upvotes: 2

KoPoCabana
KoPoCabana

Reputation: 90

Do it with LINQ, which will just go once through the list being very efficient.

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

Upvotes: 0

Ivan Stoev
Ivan Stoev

Reputation: 205569

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:

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

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

Upvotes: 1

Related Questions