Qual é a maneira mais eficiente de escrever a velha escola:
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();
... em LINQ?
c#
linq
string-concatenation
tags2k
fonte
fonte
Respostas:
Esta resposta mostra o uso de LINQ (
Aggregate
) conforme solicitado na pergunta e não se destina ao uso diário. Como isso não usa a,StringBuilder
ele terá um desempenho horrível por sequências muito longas. Para código regular, useString.Join
como mostrado na outra respostaUse consultas agregadas como esta:
Isso gera:
Um agregado é uma função que pega uma coleção de valores e retorna um valor escalar. Exemplos do T-SQL incluem min, max e sum. O VB e o C # têm suporte para agregados. O VB e o C # suportam agregados como métodos de extensão. Usando a notação de ponto, simplesmente chama-se um método em um objeto IEnumerable .
Lembre-se de que as consultas agregadas são executadas imediatamente.
Mais informações - MSDN: consultas agregadas
Se você realmente deseja
Aggregate
usar a variante de usoStringBuilder
proposta no comentário do CodeMonkeyKing, que seria aproximadamente o mesmo código que o normal,String.Join
incluindo bom desempenho para um grande número de objetos:fonte
""
, o primeiro valor usadocurrent
é uma sequência vazia. Portanto, para um ou mais elementos, você sempre chegará,
ao início da string.Na Net 4, há uma nova sobrecarga para
string.Join
que aceitaIEnumerable<string>
. O código ficaria assim:fonte
Por que usar o Linq?
Isso funciona perfeitamente e aceita
IEnumerable<string>
tanto quanto me lembro. Não precisa deAggregate
nada aqui que seja muito mais lento.fonte
String.Join(",", s.ToArray())
nas versões mais antigas.Você já olhou para o método de extensão Agregado?
fonte
Exemplo real do meu código:
Uma consulta é um objeto que possui uma propriedade Name, que é uma string, e eu quero os nomes de todas as consultas na lista selecionada, separados por vírgulas.
fonte
Aqui está a abordagem combinada do Join / Linq em que eu decidi depois de examinar as outras respostas e os problemas abordados em uma pergunta semelhante (a saber, que Agregado e Concatenado falham com 0 elementos).
string Result = String.Join(",", split.Select(s => s.Name));
ou (se
s
não for uma string)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) para implementarE é claro que o Join cuida da vírgula final traquina que às vezes se infiltra em outras abordagens (
for
,foreach
), e é por isso que eu estava procurando uma solução Linq em primeiro lugar.fonte
.Select()
dessa maneira fornece um local fácil para modificar cada elemento durante esta operação. Por exemplo, agrupando cada item em algum personagem como essestring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Você pode usar
StringBuilder
emAggregate
:(O
Select
está lá apenas para mostrar que você pode fazer mais coisas sobre o LINQ.)fonte
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
o linq e removendo-o.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
dados de desempenho rápido para o caso StringBuilder vs Select & Aggregate, com mais de 3000 elementos:
Teste de unidade - Duração (segundos)
LINQ_StringBuilder - 0.0036644
LINQ_Select.Aggregate - 1.8012535
fonte
Eu sempre uso o método de extensão:
fonte
string.Join
no .net 4 já pode levar umIEnumerable<T>
para qualquer arbitrárioT
.Por 'maneira super bacana do LINQ ', você pode estar falando sobre o modo como o LINQ torna a programação funcional muito mais agradável com o uso de métodos de extensão. Quero dizer, o açúcar sintático que permite que as funções sejam encadeadas de maneira visualmente linear (uma após a outra) em vez de aninhar (uma dentro da outra). Por exemplo:
pode ser escrito assim:
Você pode ver como o segundo exemplo é mais fácil de ler. Você também pode ver como mais funções podem ser adicionadas com menos problemas de recuo ou os pontos de fechamento do Lispy aparecendo no final da expressão.
Muitas das outras respostas afirmam que esse
String.Join
é o caminho a seguir, porque é a mais rápida ou mais simples de ler. Mas se você entender minha interpretação de ' maneira LINQ super bacana ', a resposta é usá-la,String.Join
mas envolva-a em um método de extensão no estilo LINQ que permitirá que você encadeie suas funções de uma maneira visualmente agradável. Então, se você quiser escrever,sa.Concatenate(", ")
basta criar algo como isto:Isso fornecerá um código com desempenho tão alto quanto a chamada direta (pelo menos em termos de complexidade do algoritmo) e, em alguns casos, poderá tornar o código mais legível (dependendo do contexto), especialmente se outro código do bloco estiver usando o estilo de função em cadeia .
fonte
Existem várias respostas alternativas nesta pergunta anterior - que reconhecidamente estava mirando uma matriz inteira como a fonte, mas recebeu respostas generalizadas.
fonte
Aqui está usando LINQ puro como uma única expressão:
E é muito rápido!
fonte
Vou trapacear um pouco e dar uma nova resposta a isso que parece resumir o melhor de tudo aqui em vez de colocá-lo dentro de um comentário.
Então você pode uma linha isso:
Editar: você deseja verificar primeiro um enumerável vazio ou adicionar um
.Replace("\a",string.Empty);
no final da expressão. Acho que eu poderia estar tentando ficar um pouco inteligente demais.A resposta de @ a.friend pode ser um pouco mais eficiente, não sei o que o Replace faz sob o capô em comparação com o Remove. A única outra ressalva, se por algum motivo você quisesse concatenar strings que terminassem em \ a's, você perderia seus separadores ... Acho isso improvável. Se for esse o caso, você tem outros personagens sofisticados para escolher.
fonte
Você pode combinar o LINQ e com
string.join()
bastante eficiência. Aqui estou removendo um item de uma string. Também existem maneiras melhores de fazer isso, mas aqui está:fonte
Muitas opções aqui. Você pode usar o LINQ e um StringBuilder para obter o desempenho da seguinte forma:
fonte
builder.Length > 0
na ForEach e removendo a primeira vírgula após o ForEachFiz o seguinte rápido e sujo ao analisar um arquivo de log do IIS usando linq, funcionou muito bem a 1 milhão de linhas (15 segundos), embora tenha ocorrido um erro de falta de memória ao tentar 2 milhões de linhas.
A verdadeira razão pela qual usei o linq foi para um Distinct () que eu precisava anteriormente:
fonte
Eu escrevi sobre isso há um tempo atrás, o que eu fiz para ser exatamente o que você está procurando:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
Na postagem do blog, descreva como implementar métodos de extensão que funcionam no IEnumerable e são nomeados Concatenar, permitindo escrever coisas como:
Ou coisas mais elaboradas, como:
fonte