Какой самый эффективный способ написания старой школы:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
... в LINQ?
c#
linq
string-concatenation
tags2k
источник
источник
Ответы:
Этот ответ показывает использование LINQ (
Aggregate
) в соответствии с запросом в вопросе и не предназначен для повседневного использования. Поскольку это не использует,StringBuilder
это будет иметь ужасную производительность для очень длинных последовательностей. Для обычного использования кода,String.Join
как показано в другом ответеИспользуйте совокупные запросы, как это:
Это выводит:
Агрегат - это функция, которая принимает коллекцию значений и возвращает скалярное значение. Примеры из T-SQL включают min, max и sum. И VB, и C # поддерживают агрегаты. И VB, и C # поддерживают агрегаты в качестве методов расширения. Используя точечную запись, вы просто вызываете метод объекта IEnumerable .
Помните, что совокупные запросы выполняются немедленно.
Дополнительная информация - MSDN: агрегированные запросы
Если вы действительно хотите
Aggregate
использовать вариант с использованиемStringBuilder
предложенного в комментарии CodeMonkeyKing, который будет примерно таким же, как обычный, сString.Join
хорошей производительностью для большого количества объектов:источник
""
начинаете с первого значения, используетсяcurrent
пустая строка. Таким образом, для 1 или более элементов, вы всегда получите,
в начале строки.В .Net 4, есть новая перегрузка на
string.Join
который принимаетIEnumerable<string>
. Код будет выглядеть так:источник
Зачем использовать Linq?
Это прекрасно работает и принимает любое,
IEnumerable<string>
насколько я помню. Здесь не нужноAggregate
ничего более медленного.источник
String.Join(",", s.ToArray())
в старых версиях, хотя.Вы смотрели на метод совокупного расширения?
источник
Реальный пример из моего кода:
Запрос - это объект со свойством Name, представляющим собой строку, и я хочу, чтобы имена всех запросов в выбранном списке были разделены запятыми.
источник
Вот комбинированный подход Join / Linq, на котором я остановился, посмотрев на другие ответы и проблемы, затронутые в аналогичном вопросе (а именно, что Aggregate и Concatenate терпят неудачу с 0 элементами).
string Result = String.Join(",", split.Select(s => s.Name));
или (если
s
не строка)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) для реализацииИ, конечно же, Join заботится о досадной последней запятой, которая иногда проникает в другие подходы (
for
,foreach
), именно поэтому я искал решение Linq в первую очередь.источник
.Select()
что такое использование обеспечивает удобное место для изменения каждого элемента во время этой операции. Например, упаковка каждого элемента в какой - то персонаж , как такstring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Вы можете использовать
StringBuilder
вAggregate
:(Это
Select
только для того, чтобы показать, что вы можете делать больше вещей LINQ.)источник
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
в linq и убирая его.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
быстрые данные о производительности для случая StringBuilder и Select & Aggregate для более чем 3000 элементов:
Модульный тест - Длительность (секунды) LINQ_StringBuilder - 0.0036644
LINQ_Select.Aggregate - 1.8012535
источник
Я всегда использую метод расширения:
источник
string.Join
в .net 4 уже можно взятьIEnumerable<T>
любой произвольныйT
.Под « супер-классным способом LINQ » вы можете говорить о том, как LINQ делает функциональное программирование намного более приемлемым с использованием методов расширения. Я имею в виду синтаксический сахар, который позволяет связывать функции визуально линейным способом (один за другим) вместо вложения (один внутри другого). Например:
можно написать так:
Вы можете видеть, как второй пример легче читать. Вы также можете увидеть, как можно добавить больше функций с меньшим количеством проблем с отступами или закрывающих слов в Lispy, появляющихся в конце выражения.
Многие другие ответы утверждают, что
String.Join
это путь, потому что он самый быстрый или простой для чтения. Но если вы возьмете мою интерпретацию « супер-крутого пути LINQ », то ответ будет использовать,String.Join
но оберните его в метод расширения стиля LINQ, который позволит вам связать ваши функции визуально приятным способом. Так что если вы хотите написать,sa.Concatenate(", ")
вам просто нужно создать что-то вроде этого:Это обеспечит код, который является таким же быстродействующим, как и прямой вызов (по крайней мере, с точки зрения сложности алгоритма), и в некоторых случаях может сделать код более читабельным (в зависимости от контекста), особенно если другой код в блоке использует стиль связанной функции ,
источник
Существуют различные альтернативные ответы на этот предыдущий вопрос - который, по общему признанию, был нацелен на целочисленный массив в качестве источника, но получил обобщенные ответы.
источник
Здесь он использует чистый LINQ в качестве одного выражения:
И это чертовски быстро!
источник
Я собираюсь немного обмануть и выкинуть новый ответ на этот вопрос, который, кажется, суммирует лучшее из всего, что здесь есть, вместо того, чтобы вставлять его в комментарий.
Таким образом, вы можете в одну строку это:
Редактировать: вы либо захотите сначала проверить наличие пустого перечислимого, либо добавить
.Replace("\a",string.Empty);
в конец выражения. Думаю, я пытался стать слишком умным.Ответ от @ a.friend может быть немного более производительным, я не уверен, что Replace делает под капотом по сравнению с Remove. Единственное другое предостережение, если по какой-то причине вы хотите объединить строки, заканчивающиеся на \ a, вы потеряете свои разделители ... Я считаю это маловероятным. Если это так, у вас есть другие необычные персонажи на выбор.
источник
Вы можете комбинировать LINQ и
string.join()
довольно эффективно. Здесь я удаляю элемент из строки. Есть и лучшие способы сделать это, но вот оно:источник
Много вариантов здесь. Вы можете использовать LINQ и StringBuilder, чтобы получить производительность, например, так:
источник
builder.Length > 0
в ForEach и удалив первую запятую после ForEachЯ быстро и грязно сделал следующее при разборе файла журнала IIS с помощью linq, он сработал примерно на 1 миллион строк (15 секунд), хотя при попытке выполнить 2 миллиона строк возникла ошибка нехватки памяти.
Реальная причина, по которой я использовал linq, заключалась в необходимости использовать Distinct (), который мне ранее был необходим:
источник
Я писал об этом некоторое время назад, то, что я сделал швы, чтобы быть именно тем, что вы ищете:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
В посте блога описывается, как реализовать методы расширения, которые работают в IEnumerable и называются Concatenate, это позволит вам писать такие вещи, как:
Или более сложные вещи, такие как:
источник