2009-07-14 9 views
9

mam jakiś kod LINQ, który generuje listę ciągów coś takiego:Najszybszy sposób konwertowania listy ciągów znaków w pojedynczy połączony ciąg znaków?

var data = from a in someOtherList 
      orderby a 
      select FunctionThatReturnsString(a); 

Jak mogę przekonwertować listy ciągów w jeden wielki połączonego łańcucha? Załóżmy, że dane mają te wpisy:

"Some " 
"resulting " 
"data here." 

powinienem skończyć z jednym ciągiem, który wygląda tak:

"Some resulting data here." 

Jak mogę to zrobić szybko? Pomyślałem o tym:

StringBuilder sb = new StringBuilder(); 
data.ToList().ForEach(s => sb.Append(s)); 
string result = sb.ToString(); 

Ale to po prostu nie wydaje się właściwe. Jeśli jest to właściwe rozwiązanie, w jaki sposób mam zamiar przekształcić to w metodę rozszerzającą?

Odpowiedz

22

Jak o:

public static string Concat(this IEnumerable<string> source) { 
    StringBuilder sb = new StringBuilder(); 
    foreach(string s in source) { 
     sb.Append(s); 
    } 
    return sb.ToString(); 
} 

oraz:

string s = data.Concat(); 

to wtedy nie ma potrzeby dodatkowego ToList()/ToArray() kroku.

+0

+1 To nie jest najkrótsza metoda, ale OP najwyraźniej prosi o * najszybszą *, a to faktycznie bije za pomocą 'ToArray()' po 'ciąg.Concat' /' string.Join'. – Noldorin

+0

@Noldorin: Najszybszy jest nieco niezdefiniowany;) Dla programisty lub komputera? –

+0

Dzięki! Najszybciej mówiłem o czasie biegu. – jasonh

16

Czy próbowałeś String.Join? Jeśli już chcesz wziąć na siebie obciążenie wywołania funkcji .ToList, zamiast tego użyj funkcji .ToArray() i połącz ją z wywołaniem String.Join.

var joined = String.Concat(someQuery.ToArray()); 

Uwaga: Moje rozwiązanie prawdopodobnie nie jest najszybsze, ponieważ wiąże się z pewnym obciążeniem w tablicy. Podejrzewam, że szybszy będzie marsz bardziej drogą Marca. Ale w większości przypadków, jeśli szukasz tylko szybkiego i brudnego sposobu na zrobienie tego w kodzie, moja trasa zadziała.

+2

Jakiś szczególny powód, aby nie używać 'string.Concat'? –

+0

@Mehrdad, nie, Join był tylko pierwszym, który pojawił się dzisiaj w mojej głowie. – JaredPar

+0

W moich testach wydajność jest szyjka i szyja z rozwiązaniem Marca (dla szerokiej gamy ciągów i długości kolekcji), więc dostaję mój głos. – LukeH

3

Use "agregat" tak:

List<string> strings = new List<string>() {"bob", "steve", "jane"}; 
    string result = strings.Aggregate((working, next) => working + next); 
    Console.WriteLine(result); 

Uwaga: Agregat jest w przestrzeni nazw System.Linq jako metodę rozszerzenia.

+3

To może być *** dużo *** pośrednich ciągów ... –

0

W zależności od optymalizacji JIT, metoda string.Concat() lub Marc z StringBuilder może być szybsza. Ponieważ używasz Linq tutaj, będę zakładać, wydajność nie jest absolutnym wymogiem nr 1, w którym to przypadku pójdę z najłatwiej odczytać:

string.Concat(data.ToArray()); 

Edit: tylko wtedy, gdy dane są IEnumerable typu wartości, trzeba oddać go do IEnumerable <obiektu>:

string.Concat(data.Cast<object>().ToArray()) 

Edycja 2: naprawdę nie znaczy LINQ jest powolny. Mam na myśli tylko to, że różnica prędkości pomiędzy tymi dwoma sposobami, o których wspomniałem, powinna być bardzo minimalna, jeśli nawet mierzalna.

Edycja 3: JIT optymalizuje prawie wszystkie operacje na klasie String, więc pojedyncze wywołanie wewnętrznego środowiska wykonawczego string.Concat może być naprawdę szybsze niż przy użyciu StringBuilder. Nie jestem tego pewien, ale powinieneś to sprawdzić, żeby się upewnić.

+0

Od kiedy Linq jest równoznaczny z powolnym? –

+0

Dodałem edycję 2, aby wyjaśnić, przepraszam. :) –

+0

Dlaczego zrobiłbyś 'data.Cast ()' zamiast czegoś w rodzaju 'data.Select (x => x.ToString())'? – LukeH

1
data.ToList().Aggregate(new StringBuilder(), (sb, s) => sb.Append(s)).ToString(); 
0

Alternatywa:

>>> data = ['Some ', 'resulting ', 'data here.'] 
>>> s = ''.join(data) 
>>> s 
'Some resulting data here.' 
1

Można użyć tego oświadczenia. String.Join ("", someOtherList);

+0

Czy możesz wyjaśnić nieco więcej? –

+0

Może nie najszybszy, ale najprostszy! – newman

Powiązane problemy