Reputation: 25
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
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
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
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