Wie konvertiere ich alle Zeichenfolgen in List <string> mit LINQ in Kleinbuchstaben?

94

Ich habe gestern in einer der Antworten hier auf StackOverflow einen Code-Ausschnitt gesehen, der mich fasziniert hat. Es war ungefähr so:

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

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

Ich hatte gehofft, damit alle Elemente in myList in Kleinbuchstaben konvertieren zu können. Es passiert jedoch nicht ... nachdem dies ausgeführt wurde, bleibt das Gehäuse in myList unverändert.

Meine Frage ist also, ob es eine Möglichkeit gibt, LINQ- und Lambda-Ausdrücke zu verwenden, um den Inhalt einer Liste auf ähnliche Weise einfach zu durchlaufen und zu ändern.

Danke, Max

Max Schilling
quelle

Antworten:

180

Einfachster Ansatz:

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

Nicht zu viel anders als Ihr Beispielcode. ForEachSchleift die ursprüngliche Liste, während ConvertAlleine neue erstellt wird, die Sie neu zuweisen müssen.

Jason Bunting
quelle
4
Keine Erweiterungsmethode.
Leppie
@leppie: Stimmt, es ist nicht - guter Fang. In diesem Fall ist die Sorge, ob es sich um eine Instanzmethode oder eine Erweiterungsmethode handelt, zwar etwas umständlich, aber auf jeden Fall korrekt. :)
Jason Bunting
Und String ist unveränderlich: P
Sherlock
48

Dies liegt daran, dass ToLower eine Zeichenfolge in Kleinbuchstaben zurückgibt, anstatt die ursprüngliche Zeichenfolge zu konvertieren. Sie möchten also so etwas:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();
Ryan Lundy
quelle
1
Ich mag diesen Ansatz besser als die akzeptierte Antwort, da Sie ihn mit jedem IEnumerable <string> verwenden können, nicht nur mit List <string>.
Joshua Pech
6
Diese Lösung funktioniert auch in .NET Core. ConvertAll ist in .NET Core nicht vorhanden.
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
quelle
3

ForEachverwendet Action<T>, was bedeutet, dass Sie beeinflussen könnten, xwenn es nicht unveränderlich wäre. Da xes sich um a handelt string, ist es unveränderlich, sodass nichts, was Sie im Lambda damit tun, seine Eigenschaften ändert. Die Lösung von Kyralessa ist die beste Option, es sei denn, Sie möchten eine eigene Erweiterungsmethode implementieren, mit der Sie einen Ersatzwert zurückgeben können.

Michael Meadows
quelle
Bitte recherchieren Sie weiter, wenn Sie sich nicht sicher sind ... erinnern Sie sich an etwas?
Patrick Desjardins
Der Fehler ist menschlich, der Link, den ich bereitgestellt habe, war 3,5 in Fettdruck und 2,0 in Normal, ich habe ihn nicht gesehen. Ich habe meinen Beitrag gelöscht ... ein einfacher Kommentar von Ihnen hätte gereicht. Sie möchten ohne Grund abstimmen, als jetzt annehmen.
Patrick Desjardins
Obwohl ich dies fast ein Jahr später schreibe und obwohl ich kein Daok bin, werde ich Ihnen sagen, warum Ihre Antwort "falsch" ist - Sie sagten "Kyralessas Lösung ist Ihre beste Option", wenn dies nicht der Fall ist - meine Lösung ist sauberer und klarer.
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
quelle