2009-10-06 6 views
74

Gibt es eine Möglichkeit, eine Liste zu nehmen und in eine kommagetrennte Zeichenkette umzuwandeln?Konvertieren einer Liste <int> in eine durch Kommas getrennte Zeichenkette

Ich weiß, ich kann es einfach schleifen und bauen, aber irgendwie denke ich, dass einige von euch eine coolere Art, es zu tun?

Ich möchte diese Art von "Tricks" wirklich lernen, also bitte erklären oder verlinken Sie die Dokumente auf der Methode, die Sie verwenden.

Antwort

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

Clever aber langsam und aufgebläht, da es eine Zeichenfolge pro Element zuweist. Die Verwendung eines StringBuilders wäre viel effizienter. –

+3

Von dem, was ich online sah (Schnellsuche) String.Join ist schneller als mit einem StringBuilder. –

+3

http://stackoverflow.com/questions/585860/string-join-vstringbuilder-which-is-faster, Sie sind falsch Steven –

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

Großartig, wenn Sie .NET 4 nicht verwenden können –

1

My "clever" Eintrag:

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

haben einfach nicht begriffen, wie bedingt das Komma hinzuzufügen.

+1

Bitte schreiben Sie nicht "Select" mit Nebenwirkungen im Lambda. In diesem Fall benutzen Sie nicht einmal 'y', also ist Ihr' Select' im Wesentlichen nur eine 'foreach' - also schreiben Sie es als solches. –

+0

Ich schlug dies nicht als eine gute Lösung vor. OP wollte etwas Interessanteres als Foreach. – Larsenal

+0

Ja, aber 'Select' zu missbrauchen, weil' foreach' über "interessant" hinausgeht und in, nun, "missbrauchen". Ein interessanterer Ansatz wäre hier die Verwendung von 'Enumerable.Aggregate' mit' StringBuilder' als Startwert - probiere das aus. –

3

Für zusätzliche Kühle würde ich dies eine Erweiterungsmethode auf IEnumerable < T machen>, so dass es auf jedem IEnumerable funktioniert:

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

Verwenden Sie es wie folgt:

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

Zwei mögliche Optimierungen: 1) Fügen Sie das Delimeter nach jedem Element unabhängig an, und entfernen Sie das zusätzliche, nachdem die Schleife beendet ist. 2) Geben Sie eine Kapazität für den StringBuilder an. –

+1

Wenn Sie Reflector ausgraben, stellt sich heraus, dass Join die Längen zur Vorberechnung der Puffergröße zusammenfasst und auch die Pumpe "primert", indem sie die erste Zeichenfolge außerhalb der Schleife anfügt und dann innerhalb der Schleife unbedingt das Trennzeichen vor anfügt die nächste Zeichenfolge. Zusammen mit einigen unsicheren/internen Tricks sollte es sehr schnell gehen. –

+0

@ Steven: folgte Ihrem Rat. – cdiggins

6

für etwa eine Unmenge Lösungen zu einer etwas komplizierteren Version dieses Problems - von denen viele langsam, fehlerhaft oder nicht einmal kompilieren - siehe die Kommentare zu meinem Artikel zu diesem Thema:

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

und die Stackoverflow Kommentar:

Eric Lippert's challenge "comma-quibbling", best answer?

+0

Danke für den Link. Dieses String-Verkettungsproblem hat sich als komplexer und lehrreicher herausgestellt, als ich erwartet hatte! –

1

leidlich schnell zu sein scheint.

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

Einfache Lösung ist

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

ich es in meinem Code gerade jetzt verwendet wird, arbeitet funtastic.

+0

Vielen Dank! Das ist ein schöner Ansatz –

Verwandte Themen