¿Cómo convertir todas las cadenas en List <string> a minúsculas usando LINQ?

94

Ayer vi un fragmento de código en una de las respuestas aquí en StackOverflow que me intrigó. Fue algo como esto:

 List<string> myList = new List<string> {"aBc", "HELLO", "GoodBye"};

 myList.ForEach(d=>d.ToLower());

Esperaba poder usarlo para convertir todos los elementos en myList a minúsculas. Sin embargo, no sucede ... después de ejecutar esto, la carcasa en myList permanece sin cambios.

Entonces, mi pregunta es si hay una manera, usando expresiones LINQ y Lambda para iterar y modificar fácilmente el contenido de una lista de una manera similar a esta.

Gracias Max

Max Schilling
fuente

Respuestas:

182

Enfoque más fácil:

myList = myList.ConvertAll(d => d.ToLower());

No muy diferente a su código de ejemplo. ForEachrepite la lista original mientras ConvertAllcrea una nueva que necesita reasignar.

Jason Bunting
fuente
4
No es un método de extensión.
leppie
@leppie: Es cierto, no es una buena captura. En este caso, preocuparse por si es un método de instancia o un método de extensión puede ser un poco pedante, pero definitivamente es exacto. :)
Jason Bunting
Y la cuerda es inmutable: P
Sherlock
48

Eso es porque ToLower devuelve una cadena en minúsculas en lugar de convertir la cadena original. Entonces querrías algo como esto:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();
Ryan Lundy
fuente
1
Me gusta este enfoque más que la respuesta aceptada porque puede usar esto con cualquier IEnumerable <string>, no solo List <string>.
Joshua Pech
6
Esta solución también funciona en .NET Core, ConvertAll no existe en .NET Core.
Jonas
3
[TestMethod]
public void LinqStringTest()
{
    List<string> myList = new List<string> { "aBc", "HELLO", "GoodBye" };
    myList = (from s in myList select s.ToLower()).ToList();
    Assert.AreEqual(myList[0], "abc");
    Assert.AreEqual(myList[1], "hello");
    Assert.AreEqual(myList[2], "goodbye");
}
marcumka
fuente
3

ForEachutiliza Action<T>, lo que significa que podría afectar xsi no fuera inmutable. Dado que xes un string, es inmutable, por lo que nada de lo que le haga en el lambda cambiará sus propiedades. La solución de Kyralessa es su mejor opción a menos que desee implementar su propio método de extensión que le permita devolver un valor de reemplazo.

Michael Meadows
fuente
Por favor, investigue más si no está seguro ... ¿recuerda algo?
Patrick Desjardins
El error es humano, el enlace que proporcioné tenía 3.5 en negrita y 2.0 en normal, no lo he visto. He eliminado mi publicación ... un simple comentario tuyo hubiera sido suficiente. Quieres votar en contra sin motivo alguno, de lo que ahora se supone.
Patrick Desjardins
Aunque escribo esto casi un año después, y aunque no soy Daok, te diré por qué tu respuesta es "incorrecta" - dijiste "La solución de Kyralessa es tu mejor opción" cuando no lo es - mi solución es más limpia y más claro.
Jason Bunting
-1
var _reps = new List(); // with variant data

_reps.ConvertAll<string>(new Converter<string,string>(delegate(string str){str = str.ToLower(); return str;})).Contains("invisible"))
Uhlamurile
fuente