Как преобразовать все строки в списке в нижний регистр с помощью LINQ?


Я видел фрагмент кода вчера в одном из ответов здесь на StackOverflow, который заинтриговал меня. Это было что-то вроде этого:

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

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

Я надеялся, что смогу использовать его для преобразования всех элементов в myList в нижний регистр. Однако этого не происходит... после запуска этого, корпус в myList остается неизменным.

Так что мой вопрос, есть ли способ, используя LINQ и лямбда-выражения легко перебирать и изменять содержимое списка аналогично этот.

спасибо, Макс

5 78

5 ответов:

самый простой подход:

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

не слишком сильно отличается от вашего примера кода. ForEach петли исходного списка, в то время как ConvertAll создает новый, который нужно переназначить.

Это потому что ToLower возвращает строка в нижнем регистре вместо преобразования исходной строки. Так что вы хотели бы что-то вроде этого:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();
[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");
}

ForEach использует Action<T>, что означает, что вы можете повлиять на x если бы он не был неизменным. Так как x это string, она неизменна, поэтому ничего из того, что вы делаете с ней в лямбде, не изменит ее свойств. Решение Kyralessa - это ваш лучший вариант, если вы не хотите реализовать свой собственный метод расширения, который позволяет вам возвращать значение замены.

var _reps = new List(); // with variant data

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