2009-07-14 1 views
9

У меня есть некоторые LINQ код, который генерирует список строк, как это:Самый быстрый способ преобразования списка строк в одну конкатенированную строку?

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

Как преобразовать этот список строк в одну большую каскадную строку? Допустим, что данные имеют следующие записи:

"Some " 
"resulting " 
"data here." 

я должен закончить с одной строкой, которая выглядит следующим образом:

"Some resulting data here." 

Как я могу сделать это быстро? Я подумал об этом:

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

Но это просто не кажется правильным. Если это правильное решение, как я могу превратить это в метод расширения?

ответ

22

Как насчет:

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

и:

string s = data.Concat(); 

Это то нет необходимости для дополнительной ToList()/ToArray() шаг.

+0

+1 Это не самый короткий метод, но OP явно запрашивает * fastest *, и это действительно бьет, используя 'ToArray()', следующим за строкой string.Concat/'string.Join'. – Noldorin

+0

@Noldorin: Fastest немного не определено;) Для программиста или машины? –

+0

Спасибо! Скорее всего, я имел в виду время работы. – jasonh

16

Вы пробовали String.Join? Если вы уже готовы взять накладные расходы на вызов .ToList, вместо этого используйте .ToArray() и объедините его с вызовом String.Join.

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

Примечание: Мое решение, скорее всего, не является самым быстрым, так как оно связано с небольшими издержками в массиве. Мое подозрение в том, что быстрее идти по маршруту Марка. Но в большинстве случаев, если вы просто ищете быстрый и грязный способ сделать это в коде, мой маршрут будет работать.

+2

Любая конкретная причина не использовать 'string.Concat'? –

+0

@Mehrdad, nope, Join был первым, кто появился сегодня в моей голове. – JaredPar

+0

В моих тестах производительность - шея и шея с решением Марка (для большого количества струн и длины коллекции), поэтому вы получаете мой голос. – LukeH

3

Использование "агрегат", как это:

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

Примечание: Агрегат находится в пространстве имен System.Linq в качестве метода расширения.

+3

Это может быть *** много *** промежуточных строк ... –

0

В зависимости от того, как JIT оптимизирует его, метод string.Concat() или Marc с помощью StringBuilder может быть быстрее. Так как вы используете Linq здесь, я предполагаю, что производительность не является абсолютным # 1 требование, в этом случае я бы с самым простым для чтения:

string.Concat(data.ToArray()); 

Edit: если и только если данные IEnumerable типа значение, вам нужно, чтобы бросить его в IEnumerable < объекта >:

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

Edit 2: Я не имею в виду Linq медленно. Я имею в виду только то, что разница в скорости между двумя упомянутыми мной способами должна быть чрезвычайно минимальной, даже если она измерима.

Редактировать 3: JIT оптимизирует почти все операции над классом String, поэтому один вызов во внутреннюю среду выполнения string.Concat действительно может быть быстрее, чем использование StringBuilder. Я не уверен, что это так, но вы должны проверить его, чтобы убедиться.

+0

С каких это пор Linq был эквивалентен медленному? –

+0

Я добавил редактирование # 2, чтобы уточнить, извините. :) –

+0

Зачем вы делаете 'data.Cast ()', а не что-то вроде 'data.Select (x => x.ToString())'? – LukeH

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

Альтернатива:

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

Вы можете использовать это заявление. String.Join ("", someOtherList);

+0

Можете ли вы объяснить немного больше? –

+0

Может быть, не самый быстрый, но самый простой! – newman