2009-08-07 7 views
9

Supponiamo che ho una collezione di stringhe:Generazione Comma Separated Values ​​

"foo" 
"bar" 
"xyz" 

E vorrei generare un valori separati da virgola dalla lista in qualcosa di simile:

"foo, bar, xyz" 

Avviso la mancanza di ", " alla fine.

Sono consapevole che ci sono decine di modi per generare questo:

  • uso per-loop e string.Format() o StringBuilder.
  • contatore uso intero e rimuovere la fine " 'se il valore> 0
  • non mettere'," sulla prima esecuzione
  • ecc

codice di esempio di ciò che ho ragione now:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0}, ", str); 
    return sb.Remove(0, 2).ToString(); 
} 

Qual è il codice migliore che è altamente riutilizzabile per lo scenario sopra e perché?

risposta

4

String.Join è la risposta giusta, ma nel caso di un IEnumerable, Linq è spesso più breve di un ciclo for:

someStringCollection.Aggregate((first, second) => first + ", " + second); 
+0

Bel uso di LINQ! –

26

Si desidera utilizzare il metodo string.Join, che esiste nel BCL per questo scopo.

Esempio:

var myArray = new string[] { "one", "two", "three" }; 
var output = string.Join(", ", myArray); 

Oppure, se si sta utilizzando .NET 3.5, è possibile farlo con qualsiasi IEnumerable<string> in quanto tale:

var output = string.Join(", ", myEnumerable.ToArray()); 

(Si noti che questo non dà il meglio le prestazioni richieste, anche se è chiaramente ancora "O (n)" e dovrebbero essere adatte per quasi tutti i casi).

Ora, se il vostro enumerabile non è di tipo string (genericamente un IEnumerable<T>), si può semplicemente utilizzare il metodo Select per convertire il risultato in una stringa, per esempio

var output = string.Join(", ", myEnumerable.Select(e => e.ToString()).ToArray()); 

Non sono sicuro se hai a che fare con i valori che possono potenzialmente contiene le virgole in se stessi, ma questo può essere aggirato racchiudendoli tra virgolette (") e sfuggire le virgolette, in modo simile nel formato CSV.

var output = string.Join(", ", items.Select(x => x.Contains(",") ? 
    "\"" + x.Replace("\"", "\"\"") + "\"" : x); 

Ovviamente, suddividerle di nuovo è un'operazione leggermente più complessa, che richiede un po 'di regex.

+1

Hmm ... Non sapevo che questa funzione esista (rende la mia domanda un aspetto negativo). –

+0

@Adrian: nessun problema. Se non si è da uno sfondo di .NET, la scoperta di nuove cose nel framework non è sempre semplice: è un processo onnicomprensivo di costruzione di familiarità. – Noldorin

+1

Questo è il problema, ho fatto .NET dalla prima versione. Duh. –

2

Usa

string s = string.Join (",", new string[] {"aaa", "bbb", "ccc"}); 
3
string finalstr = String.Join(",", strs); 
0

Se si dispone di un array di stringhe, andare con la soluzione Noldorin s'.

Ma se è un altro tipo di raccolta, potrei fare questo:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0} {1}", (0 == sb.Length ? "" : ","), str); 
    return sb.ToString(); 
} 
4

Come altri hanno detto: String.Join è normalmente il modo migliore per farlo. Ma cosa succede se hai un IEnumerable e non un array? Forse hai il codice per enumerarli mentre li leggi da un file usando l'esecuzione posticipata. In questo caso, String.Join non è altrettanto bello, perché è necessario eseguire il loop delle stringhe due volte — una volta per creare l'array e una volta per aggiungerlo. In questo caso, si desidera qualcosa di più simile a questo:

public static string ToDelimitedString(this IEnumerable<string> source, string delimiter) 
{ 
    string d = ""; 
    var result = new StringBuilder(); 

    foreach(string s in source) 
    { 
     result.Append(d).Append(s); 
     d = delimiter; 
    } 
    return result.ToString(); 
} 

Questo eseguirà quasi così come String.Join, e lavora nel caso più generale. Poi, dato un array di stringhe o di qualsiasi altro IEnumerable si può chiamare in questo modo:

string finalStr = MyStrings.ToDelimitedString(","); 
+0

Sì, è apparentemente lo scenario più comune. IEnumerable rispetto alla stringa []. –

+0

+1 Il 'result.Append (d) .Append (s)' è interessante ... non ci ha mai pensato. Sarebbe un po 'bello vedere quanti modi diversi questo semplice compito è attualmente in corso. –

+0

La cosa veramente interessante è che il jitter normalmente ottimizzerà i compiti extra, quindi il codice fa esattamente ciò che vuoi o. –

Problemi correlati