Comment convertir toutes les chaînes de la liste <chaîne> en minuscules à l'aide de LINQ?

94

J'ai vu hier un extrait de code dans l'une des réponses ici sur StackOverflow qui m'a intrigué. C'était quelque chose comme ça:

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

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

J'espérais pouvoir l'utiliser pour convertir tous les éléments de ma liste en minuscules. Cependant, cela ne se produit pas ... après avoir exécuté cela, la casse dans myList reste inchangée.

Ma question est donc de savoir s'il existe un moyen d'utiliser les expressions LINQ et Lambda pour parcourir et modifier facilement le contenu d'une liste d'une manière similaire à celle-ci.

Merci, Max

Max Schilling
la source

Réponses:

182

Approche la plus simple:

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

Pas trop différent de votre exemple de code. ForEachboucle la liste d'origine tandis ConvertAllqu'en crée une nouvelle que vous devez réaffecter.

Jason Bunting
la source
4
Pas une méthode d'extension.
leppie
@leppie: C'est vrai, ce n'est pas - bonne prise. Dans ce cas, se soucier de savoir s'il s'agit d'une méthode d'instance ou d'une méthode d'extension peut être un peu pédant, mais c'est certainement exact. :)
Jason Bunting
Et la chaîne est immuable: P
Sherlock
48

C'est parce que ToLower renvoie une chaîne en minuscules plutôt que de convertir la chaîne d'origine. Donc, vous voudriez quelque chose comme ça:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();
Ryan Lundy
la source
1
J'aime mieux cette approche que la réponse acceptée car vous pouvez l'utiliser avec n'importe quelle <chaîne> IEnumerable, pas seulement avec List <chaîne>.
Joshua Pech
6
Cette solution fonctionne également dans .NET Core, ConvertAll n'existe pas dans .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
la source
3

ForEachutilise Action<T>, ce qui signifie que vous pourriez affecter xs'il n'était pas immuable. Puisque xest a string, il est immuable, donc rien de ce que vous lui faites dans le lambda ne changera ses propriétés. La solution de Kyralessa est votre meilleure option, sauf si vous souhaitez implémenter votre propre méthode d'extension qui vous permet de renvoyer une valeur de remplacement.

Michael Meadows
la source
Veuillez faire plus de recherches si vous n'êtes pas sûr ... vous vous souvenez de quelque chose?
Patrick Desjardins
L'erreur est humaine, le lien que j'ai fourni avait 3,5 en gras et 2,0 en normal, je ne l'ai pas vu. J'ai supprimé mon message ... un simple commentaire de votre part aurait suffi. Vous voulez voter sans raison, alors que vous ne le pensez maintenant.
Patrick Desjardins
Bien que j'écris ceci presque un an plus tard, et bien que je ne sois pas Daok, je vais vous dire pourquoi votre réponse est "fausse" - vous avez dit "la solution de Kyralessa est votre meilleure option" quand ce n'est pas le cas - ma solution est plus propre et plus clair.
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
la source