Convertendo uma Lista <int> em uma string separada por vírgulas


116

Existe uma maneira de pegar uma lista e convertê-la em uma string separada por vírgulas?

Eu sei que posso apenas fazer um loop e construir, mas de alguma forma eu acho que alguns de vocês são uma maneira mais legal de fazer isso?

Eu realmente quero aprender esses tipos de 'truques', então explique ou crie um link para a documentação sobre o método que você usa.

Respostas:


189
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())

7
Inteligente, mas lento e inchado, pois aloca uma string por elemento. Usar um StringBuilder seria muito mais eficiente.
Steven Sudit

3
Pelo que vi online (pesquisa rápida), String.Join é mais rápido do que usar um StringBuilder.
Yuriy Faktorovich


6
Acho que Steven está se referindo à parte n.ToString () em vez de String.Join.
Larsenal

9
Larsenal: mas StringBuilder.Append (Int32) chama internamente ToString no inteiro de qualquer maneira. StringBuilder não evita magicamente o custo de alocar uma string para cada elemento; ele simplesmente o esconde.
itowlson

115

Solução simples é

List<int> list = new List<int>() {1,2,3};
string.Join<int>(",", list)

Eu usei agora mesmo no meu código, funcionando de forma fantástica.


1
Obrigado! esta é uma bela abordagem
Irfan Ashraf

2
Esta é uma abordagem melhor do que a resposta aceita. Com essa abordagem, você não precisa importar o Linq e isso é mais rápido.
JoKeRxbLaCk

Legal! Eu nunca conheci string.Join tem sobrecargas genéricas. Obrigado.
mrmashal

10
List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(String.Join(",", list.Select(i => i.ToString()).ToArray()));

Ótimo se você não pode usar o .NET 4
Greg Woods,

6

Para cerca de um zilhão de soluções para uma versão um pouco mais complicada deste problema - muitos dos quais são lentos, com erros ou nem mesmo compilam - consulte os comentários do meu artigo sobre este assunto:

http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-quibbling.aspx

e o comentário StackOverflow:

O desafio de Eric Lippert de "trocadilhos", melhor resposta?


Obrigado pelo link. Esse problema de concatenação de strings acabou se tornando mais complexo e mais educacional do que eu esperava!
Steven Sudit,

4

Para maior frieza, eu faria disso um método de extensão em IEnumerable <T> para que funcione em qualquer IEnumerable:

public static class IEnumerableExtensions {
  public static string BuildString<T>(this IEnumerable<T> self, string delim = ",") {
    return string.Join(delim, self)        
  }
}

Use-o da seguinte maneira:

List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list.BuildString(", "));

Duas otimizações possíveis: 1) Acrescente o delimitador após cada item independentemente e, em seguida, remova o extra após o término do loop. 2) Especifique uma capacidade para o StringBuilder.
Steven Sudit,

1
Se você cavar o Reflector, descobre-se que Join soma os comprimentos para pré-calcular o tamanho do buffer e também "prepara a bomba" anexando a primeira string fora do loop e, em seguida, dentro do loop, incondicionalmente anexando o delimitador antes do próxima string. Combinado com alguns truques inseguros / internos, deve ser muito rápido.
Steven Sudit,

@Steven: seguiu seu conselho.
cdiggins

1
Você codifica o delimitador em sua extensão e ignora o valor passado para um delimitador, e perdeu o ponto-e-vírgula. Deveria serreturn string.Join(delim, self);
Andrew

1

Parece razoavelmente rápido.

IList<int> listItem = Enumerable.Range(0, 100000).ToList();
var result = listItem.Aggregate<int, StringBuilder, string>(new StringBuilder(), (strBuild, intVal) => { strBuild.Append(intVal); strBuild.Append(","); return strBuild; }, (strBuild) => strBuild.ToString(0, strBuild.Length - 1));

1

Minha entrada "inteligente":

        List<int> list = new List<int> { 1, 2, 3 };
        StringBuilder sb = new StringBuilder();
        var y = list.Skip(1).Aggregate(sb.Append(x.ToString()),
                    (sb1, x) =>  sb1.AppendFormat(",{0}",x));

        // A lot of mess to remove initial comma
        Console.WriteLine(y.ToString().Substring(1,y.Length - 1));

Só não descobri como adicionar condicionalmente a vírgula.


1
Por favor, não escreva Selectcom efeitos colaterais no lambda. Neste caso, você nem mesmo está usando y, portanto, Selecté essencialmente apenas um foreach- então escreva como tal.
Pavel Minaev

Não estava sugerindo que fosse uma boa solução. OP queria algo mais interessante do que foreach.
Larsenal,

Sim, mas abusando Selectcomo foreachvai passado "interessante" e para, assim, "abuso". Uma abordagem mais interessante aqui seria usar Enumerable.Aggregatecom StringBuilderum valor de semente - tente isso.
Pavel Minaev

Boa ideia. Eu tenho que sair, mas posso dar um giro.
Larsenal,

0

você pode usar a biblioteca System.Linq; É mais eficiente:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.