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.

mrblah
fonte

Respostas:

189
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())
Pavel Minaev
fonte
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
3
stackoverflow.com/questions/585860/… , você está incorreto Steven
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.

Nitin Daware
fonte
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()));
Yuriy Faktorovich
fonte
Ó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?

Eric Lippert
fonte
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(", "));
cdiggins
fonte
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));
Gregory
fonte
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.

Larsenal
fonte
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));
Maurico bello
fonte