2009-12-30 18 views
5

Mam listę takich jak:Wyrażenie Lambda, jak wykonać String.Format na liście <String>?

List<String> test = new List<String> {"Luke", "Leia"}; 

chciałbym użyć czegoś takiego:

test.Select(s => String.Format("Hello {0}", s)); 

ale nie dostosować nazwy na liście. Czy istnieje sposób na użycie wyrażeń lambda, aby je zmienić? A może dlatego, że ciągi znaków są niezmienne, a to nie działa?

Odpowiedz

12

Select nie modyfikuje oryginalnej kolekcji; tworzy nową IEnumerable <T> które można wyliczyć z foreach lub konwersji do listy:

List<String> test2 = test.Select(s => String.Format("Hello {0}", s)).ToList(); 

testowym nadal zawiera "Luke" i "Leia" i test2 zawiera "Hello Luke" i "Hello Leia".


Jeśli chcesz zmodyfikować oryginalną listę wyrażenia lambda, można zastosować wyrażenia lambda do każdego elementu listy indywidualnie i zapisać wynik z powrotem w kolekcji:

Func<string, string> f = s => String.Format("Hello {0}", s); 

for (int i = 0; i < test.Count; i++) 
{ 
    test[i] = f(test[i]); 
} 
+0

Dzięki, pierwszy udało mi. –

+0

@Nyla Pareska: Ta wersja nie modyfikuje oryginalnej kolekcji, która wydawała się być twoją intencją ("ale nie zmienia nazwisk na liście"). Jeśli chcesz to zrobić, zapoznaj się z metodą rozszerzenia podaną w mojej odpowiedzi. – jason

-2

może po prostu zrób oświadczenie foreach:

test.ForEach(s=>String.Format("Hello {0}", s)); 

Dzieje się tak, jeśli próbujesz po prostu zaktualizować nazwy.

+2

ForEach przyjmuje "Akcja " i nie modyfikuje 'List ' – dtb

+1

String.Format zwraca nowy ciąg, ale nie modyfikuje oryginalnego łańcucha. – M4N

+0

OK, więc zaktualizuj go jako taki: s => s = String.Format ("Hello {0}", s)); Wszystko zależy od tego, co chciał zrobić, zwróć nową listę ze zaktualizowanymi wartościami lub zaktualizuj oryginalną listę. –

3

tutaj:

for(int i = 0; i < test.Count; i++) { 
    test[i] = String.Format("Hello {0}", test[i]); 
} 

Nie trzeba być wyszukane. Nie musisz nadużywać LINQ. Po prostu to proste.

Można pójść o krok poza tym i utworzyć metodę rozszerzenia tak:

static class ListExtensions { 
    public static void AlterList<T>(this List<T> list, Func<T, T> selector) { 
     for(int index = 0; index < list.Count; index++) { 
      list[index] = selector(list[index]); 
     } 
    } 
} 

Zastosowanie:

test.AlterList(s => String.Format("Hello {0}", s)); 

Select jest do rozrzucania i jest naprawdę przeznaczone do stosowania w sytuacjach, w których istnieje nie ma żadnych skutków ubocznych. Manipulowanie przedmiotami na liście bardzo wyraźnie ma skutki uboczne. W rzeczywistości, linia

test.Select(s => String.Format("Hello {0}", s)); 

nie robi nic oprócz tworzenia IEnumerable<string>, które mogą ostatecznie być wymienione w ciągu produkować projekcji.

+1

Nie rozumiem, jak nadużywał LINQ. Używałby go dokładnie tak, jak zamierzano go użyć. Jego pytanie dotyczyło także sposobu wykonania zadania za pomocą wyrażenia lambda. –

+1

'Wybierz' nie jest przeznaczone do wywoływania efektów ubocznych. – jason

+0

@Dvvovator: proszę zostawić komentarz, dlaczego przegłosowałeś. – jason

0

Innym możliwym rozwiązaniem:

List<String> test = new List<String> {"Luke", "Leia"}; 
List<string> FormattedStrings = new List<string>(); 
test.ForEach(testVal => FormattedStrings.Add(String.Format("Hello {0}", testVal))); 
Powiązane problemy