Jak przekonwertować wszystkie ciągi w List <string> na małe litery przy użyciu LINQ?


94

Widziałem wczoraj fragment kodu w jednej z odpowiedzi na StackOverflow, który mnie zaintrygował. To było coś takiego:

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

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

Miałem nadzieję, że uda mi się go użyć do przekonwertowania wszystkich elementów w myList na małe litery. Jednak tak się nie dzieje ... po uruchomieniu tego, obudowa w myList pozostaje niezmieniona.

Moje pytanie brzmi więc, czy istnieje sposób użycia wyrażeń LINQ i Lambda do łatwego iterowania i modyfikowania zawartości listy w sposób podobny do tego.

Dzięki, Max

Odpowiedzi:


185

Najłatwiejsze podejście:

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

Nie różni się zbytnio od przykładowego kodu. ForEachzapętla oryginalną listę, podczas gdy ConvertAlltworzy nową, którą musisz ponownie przypisać.


4
Nie jest to metoda rozszerzenia.
leppie

@leppie: To prawda, nie jest - dobry chwyt. W tym przypadku martwienie się, czy jest to metoda instancji, czy metoda rozszerzająca, może być nieco pedantyczne, ale jest zdecydowanie dokładne. :)
Jason Bunting

A ciąg jest niezmienny: P
Sherlock,

49

Dzieje się tak, ponieważ ToLower zwraca ciąg z małych liter, zamiast konwertować oryginalny ciąg. Więc chciałbyś coś takiego:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();

1
Takie podejście podoba mi się bardziej niż zaakceptowana odpowiedź, ponieważ możesz jej użyć z dowolnym IEnumerable <string>, a nie tylko List <string>.
Joshua Pech

6
To rozwiązanie działa również w .NET Core, ConvertAll nie istnieje w .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");
}

3

ForEachużywa Action<T>, co oznacza, że ​​mógłbyś wpłynąć, xgdyby nie był niezmienny. Ponieważ xjest a string, jest niezmienna, więc nic, co zrobisz z nim w lambdzie, nie zmieni jego właściwości. Rozwiązanie Kyralessa jest najlepszą opcją, chyba że chcesz zaimplementować własną metodę rozszerzenia, która umożliwia zwrócenie wartości zastępczej.


Jeśli nie jesteś pewien, zbierz więcej informacji ... pamiętasz coś?
Patrick Desjardins,

Błąd jest ludzki, link, który podałem, miał 3,5 pogrubioną czcionką i 2,0 normalnie, nie widziałem. Usunąłem swój post ... wystarczyłby prosty komentarz od Ciebie. Chcesz głosować przeciw bez powodu, niż teraz załóż.
Patrick Desjardins

Chociaż piszę to prawie rok później i chociaż nie jestem Daokiem, powiem ci, dlaczego twoja odpowiedź jest „zła” - powiedziałeś „rozwiązanie Kyralessy jest najlepszą opcją”, gdy tak nie jest - moje rozwiązanie jest czystsze i jaśniejsze.
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"))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.