2009-07-14 19 views
9

Dizeler listesini üreten bazı LINQ kodlarım var, bu gibi:Dizelerin bir listesini tek bir birleştirilmiş dizeye dönüştürmenin en hızlı yolu?

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

Bu dizeleri birleştirilmiş bir dizeye nasıl dönüştürürüm? Verilerin şu girdileri içerdiğini varsayalım:

"Some " 
"resulting " 
"data here." 

Buna benzeyen bir dizeyle bitirmeliyim:

"Some resulting data here." 

Bunu nasıl hızlı bir şekilde yapabilirim? Bunu düşündüm:

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

Ancak bu doğru görünmüyor. Doğru çözümse, bunu bir uzatma yöntemine dönüştürmeyi nasıl başarabilirim?

cevap

22

. Böyle

+0

+1 Bu en kısa yöntem değil, ancak OP açıkça * en hızlı * için soruyor ve bu gerçekten de 'string.Concat' /' string.Join' tarafından takip edilen 'ToArray()' yi kullanarak atıyor. – Noldorin

+0

@Noldorin: En hızlı biraz tanımsız;) Programcı veya makine için? –

+0

Teşekkürler! En hızlı şekilde koşma zamanı demek istedim. – jasonh

16

String.Join'i denediniz mi? Zaten bir .ToList çağrısının yükünü almak istiyorsanız, bunun yerine .ToArray() öğesini kullanın ve String.Join ile bir çağrı ile birleştirin.

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

Not: dizideki yükü biraz karıştırmak gibi Çözümümün olasılıkla en hızlı değildir. Şüphem, daha çok Marc'ın rotasına gitmenin daha hızlı olacağı yönünde. Ancak çoğu durumda kodda bunu yapmak için hızlı ve kirli bir yol arıyorsanız, güzergahım işe yarayacaktır.

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

ve:

string s = data.Concat(); 

Bu da fazladan ToList()/ToArray() adım ihtiyacı yok nereden

+2

Herhangi bir nedenle 'string.Concat' kullanılmıyor? –

+0

@Mehrdad, nope, Join, bugün kafamın içine giren ilk kişi oldu. – JaredPar

+0

Testlerimde performans Marc'ın çözümüyle boyun ve boyundur (çok çeşitli dizi ve koleksiyon uzunlukları için), böylece oyumu alırsınız. – LukeH

3

Kullanım "Agrega":

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

Not: Agrega bir uzantısı yöntemi olarak System.Linq ad içindedir.

+3

Bu, ara sıra dizilerin *** lotu *** olabilir ... –

0

JIT'in nasıl en iyi duruma getirdiğine bağlı olarak, string.Concat() veya StringBuilder ile Marc'ın yöntemi daha hızlı olabilir.

string.Concat(data.ToArray()); 

Edit: ve veri yalnızca eğer burada Linq kullandığınız için, ben performans okumak için en kolay olan giderdim bu durumda mutlak 1. gereklilik değil, farz edeceğiz bir değer türüne ait IEnumerable IEnumerable <nesneye> için döküm gerekir:

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

Edit 2: gerçekten Linq yavaş anlamına gelmez. Sadece, bahsettiğim iki yol arasındaki hız farkının, ölçülebilir olsa bile, çok az olması gerektiği anlamına gelir.

Düzenleme 3: JIT, String sınıfındaki hemen hemen tüm işlemleri en iyi duruma getirir, böylece string.Concat iç çalışma zamanına yapılan tek çağrı StringBuilder'ı kullanmaktan daha hızlı olabilir. Emin değilim, ama emin olmak için test etmelisin.

+0

Linq ne zaman yavaşlamaya eşdeğer? –

+0

Açıklığa kavuşturmak için # 2 ekledim, üzgünüm. :) –

+0

Neden "data.Select (x => x.ToString())' gibi bir şeyden ziyade data.Cast () 'yapardınız? – LukeH

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

Alternatif:

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

Bu deyimi kullanabilirsiniz. String.Join ("", someOtherList);

+0

Biraz daha açıklayabilir misiniz? –

+0

Belki de en hızlı değil, en basit! – newman

İlgili konular