Conversione di un List <int> in una stringa separata da virgole


116

C'è un modo per prendere un elenco e convertirlo in una stringa separata da virgole?

So che posso semplicemente creare un loop e costruirlo, ma in qualche modo penso che alcuni di voi ragazzi un modo più interessante di farlo?

Voglio davvero imparare questi tipi di "trucchi", quindi per favore spiega o inserisci un link ai documenti sul metodo che usi.

Risposte:


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

7
Intelligente ma lento e gonfio, poiché assegna una stringa per elemento. Usare uno StringBuilder sarebbe molto più efficiente.
Steven Sudit

3
Da quello che ho visto online (ricerca rapida) String.Join è più veloce rispetto all'utilizzo di StringBuilder.
Yuriy Faktorovich


6
Penso che Steven si riferisca alla parte n.ToString () piuttosto che a String.Join.
Larsenal

9
Larsenal: ma StringBuilder.Append (Int32) chiama comunque internamente ToString sull'intero. StringBuilder non evita magicamente il costo di allocare una stringa per ogni elemento; semplicemente lo nasconde bene dalla vista.
itowlson

115

La soluzione semplice è

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

L'ho usato solo ora nel mio codice, funzionando funtastic.


1
Grazie! questo è un bellissimo approccio
Irfan Ashraf

2
Questo è un approccio migliore rispetto a quello della risposta accettata. Con questo approccio non è necessario importare Linq e questo è più veloce.
JoKeRxbLaCk

Freddo! Non ho mai saputo string.Join ha sovraccarichi generici. Grazie.
mrmashal

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

Ottimo se non puoi usare .NET 4
Greg Woods

6

Per circa un trilione di soluzioni a una versione leggermente più complicata di questo problema, molte delle quali sono lente, difettose o non si compilano nemmeno, vedere i commenti al mio articolo su questo argomento:

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

e il commento StackOverflow:

La sfida di Eric Lippert "cavilli con virgole", la migliore risposta?


Grazie per il collegamento. Questo problema di concatenazione di stringhe si è rivelato più complesso e più istruttivo di quanto mi aspettassi!
Steven Sudit

4

Per una maggiore freddezza, lo renderei un metodo di estensione su IEnumerable <T> in modo che funzioni su qualsiasi IEnumerable:

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

Usalo come segue:

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

Due possibili ottimizzazioni: 1) Aggiungi il delimetro dopo ogni elemento a prescindere, quindi rimuovi quello extra al termine del ciclo. 2) Specificare una capacità per StringBuilder.
Steven Sudit

1
Se si estrae Reflector, risulta che Join somma le lunghezze per precalcolare la dimensione del buffer, e anche "adescare la pompa" aggiungendo la prima stringa all'esterno del ciclo, e poi, all'interno del ciclo, aggiungendo incondizionatamente il delimitatore prima del stringa successiva. Combinato con alcuni trucchi interni / non sicuri, dovrebbe essere molto veloce.
Steven Sudit

@Steven: ho seguito il tuo consiglio.
cdiggins

1
Hai codificato il delimitatore nella tua estensione e ignori il valore passato per un delimitatore e hai mancato il punto e virgola. Dovrebbe esserereturn string.Join(delim, self);
Andrew

1

Sembra ragionevolmente veloce.

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

La mia voce "intelligente":

        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));

Non ho ancora capito come aggiungere in modo condizionale la virgola.


1
Per favore, non scrivere Selectcon effetti collaterali nel lambda. In questo caso non lo stai nemmeno usando y, quindi il tuo Selectè essenzialmente solo un foreach- quindi scrivilo come tale.
Pavel Minaev

Non lo stavo suggerendo come una buona soluzione. OP voleva qualcosa di più interessante di foreach.
Larsenal

Sì, ma abusare Selectcome foreachva oltre "interessante" e in, beh, "abuso". Un approccio più interessante sarebbe quella di utilizzare Enumerable.Aggregatecon StringBuilderun valore di seme - provare che.
Pavel Minaev

Buona idea. Devo uscire, ma posso fare un giro.
Larsenal

0

puoi usare, la libreria System.Linq; È più efficiente:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.