Using Array.Foreach to modify the collection

2

I want to remove spaces from the beginning and end of the string ( Trim ) in all positions of the array , but none of the forms below worked. What am I doing wrong?

var optionArray = new string[] { "in the jungle ", " the mighty jungle", " the lion sleeps tonight " };

Array.ForEach(optionArray, x => x.Trim()); // nada acontece
Array.ForEach(optionArray, x => x = x.Trim()); // nada acontece
optionArray = Array.ForEach(optionArray, x => x = x.Trim()); // Cannot implicitly convert type 'void' to 'string[]'

var optionList = optionArray.ToList();

optionList.ForEach(x => x.Trim()); // nada acontece
optionList.ForEach(x => x = x.Trim()); // nada acontece
optionList = optionList.ForEach(x => x = x.Trim()); // Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<string>'
    
asked by anonymous 26.07.2016 / 19:34

2 answers

4

Daniel completing Bigown's response, Eric Lippert in 2009 wrote a good article on his blog , it explains the hexes of using List<T>.ForEach instead of foreach . You can read the full article at the following link: “foreach” vs “ForEach”

Another argument would be that the Micrsoft architects themselves decided not to include a ForEach method in Linq , you can read about it at Why no ForEach method on IEnumerable interfaces

But in summary, you should not use List<T>.ForEach , because it violates the principles of functional programming, which can cause some side effects. in addition, List<T>.ForEach is less readable and this may imply a more difficult maintenance (try debugging an iteration within a List<T>.ForEach ).

Still, this is a scenario where this type of implementation might be useful, Paralelismo ... and even then there is a whole Namespace to handle this: https://msdn.microsoft.com/ en-us / library / system.threading.tasks.parallel (v = vs.110) .aspx

var lista = Enumerable.Range(1, 10).ToList();
Parallel.ForEach(lista, (item, state, indice) => {
    Console.WriteLine(string.Format("indice: {0}, value: {1}", indice, item));
});

But the implementation will still suffer from the same problem, you will not be able to modify the list, in this case you need to make use of Parallel.For and access the element by index.:

var lista = Enumerable.Range(1, 10).ToList();
Parallel.For(0, lista.Count, (indice, state) => {
    lista[indice] *= 2;
});

foreach(var item in lista) {
    Console.WriteLine(string.Format("value: {0}", item));
}

And finally, a good reason not to use .Select(s => s.Trim()).ToArray() , you're not modifying array values. You are creating a new array with the new values, at this point you will have two arrays in memory, then you are just wasting memory, CPU cycles and forced Garbage Collector to be called more times.

    
27.07.2016 / 14:25
1

You can use LINQ Select() , but need to create a new array :

var newArray = optionArray.Select(s => s.Trim()).ToArray();

Unless you want to do "manual" (probably what I would do):

for (var i = 0; i < optionArray.Length; i++) {
    optionArray[i] = optionArray[i].Trim();
}

See working on dotNetFiddle .

    
26.07.2016 / 19:44