Konvertieren einer Liste <int> in eine durch Kommas getrennte Zeichenfolge

114

Gibt es eine Möglichkeit, eine Liste in eine durch Kommas getrennte Zeichenfolge umzuwandeln?

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

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

mrblah
quelle

Antworten:

188
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())
Pavel Minaev
quelle
7
Clever, aber langsam und aufgebläht, da pro Element eine Zeichenfolge zugewiesen wird. Die Verwendung eines StringBuilder wäre viel effizienter.
Steven Sudit
3
Nach dem, was ich online gesehen habe (Schnellsuche), ist String.Join schneller als die Verwendung eines StringBuilder.
Yuriy Faktorovich
3
stackoverflow.com/questions/585860/… , Sie sind falsch Steven
Yuriy Faktorovich
6
Ich denke, Steven bezieht sich eher auf den Teil n.ToString () als auf den String.Join.
Larsenal
9
Larsenal: StringBuilder.Append (Int32) ruft ToString trotzdem intern für die Ganzzahl auf. StringBuilder vermeidet nicht auf magische Weise die Kosten für die Zuweisung eines Strings für jedes Element. es verstaut es einfach schön außer Sicht.
Itowlson
114

Einfache Lösung ist

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

Ich habe es gerade in meinem Code verwendet und funtastisch gearbeitet.

Nitin Daware
quelle
1
Danken! Das ist ein wunderschöner Ansatz
Irfan Ashraf
2
Dies ist ein besserer Ansatz als die akzeptierte Antwort. Mit diesem Ansatz müssen Sie Linq nicht importieren und dies ist schneller.
JoKeRxbLaCk
Cool! Ich habe String nie gekannt. Join hat generische Überladungen. Vielen Dank.
Mrmashal
10
List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(String.Join(",", list.Select(i => i.ToString()).ToArray()));
Yuriy Faktorovich
quelle
Großartig, wenn Sie .NET 4
Greg Woods
6

In den Kommentaren zu meinem Artikel zu diesem Thema finden Sie ungefähr eine Million Lösungen für eine etwas kompliziertere Version dieses Problems - von denen viele langsam, fehlerhaft oder nicht einmal kompilierbar sind:

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

und der StackOverflow-Kommentar:

Eric Lipperts Herausforderung "Komma-Quibbling", beste Antwort?

Eric Lippert
quelle
Danke für den Link. Dieses Problem mit der Verkettung von Zeichenfolgen hat sich als komplexer und lehrreicher herausgestellt, als ich erwartet hatte!
Steven Sudit
4

Für zusätzliche Coolness würde ich dies zu einer Erweiterungsmethode für IEnumerable <T> machen, damit es für jeden IEnumerable funktioniert:

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

Verwenden Sie es wie folgt:

List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list.BuildString(", "));
cdiggins
quelle
Zwei mögliche Optimierungen: 1) Hängen Sie den Begrenzer unabhängig von jedem Element an und entfernen Sie das zusätzliche nach dem Ende der Schleife. 2) Geben Sie eine Kapazität für den StringBuilder an.
Steven Sudit
1
Wenn Sie Reflector ausgraben, stellt sich heraus, dass Join die Längen zur Vorberechnung der Puffergröße summiert und außerdem die Pumpe "vorbereitet", indem der erste String außerhalb der Schleife angehängt wird und dann innerhalb der Schleife das Trennzeichen bedingungslos vor dem angehängt wird nächste Zeichenfolge. In Kombination mit einigen unsicheren / internen Tricks sollte es sehr schnell gehen.
Steven Sudit
@Steven: Befolgen Sie Ihren Rat.
Cdiggins
1
Sie haben das Trennzeichen in Ihrer Erweiterung fest codiert und den übergebenen Wert für ein Trennzeichen ignoriert und das Semikolon übersehen. Es sollte seinreturn string.Join(delim, self);
Andrew
1

Scheint ziemlich schnell.

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
quelle
1

Mein "kluger" 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));

Ich habe nur nicht herausgefunden, wie das Komma bedingt hinzugefügt werden kann.

Larsenal
quelle
1
Bitte schreiben Sie nicht Selectmit Nebenwirkungen in das Lambda. In diesem Fall verwenden Sie nicht einmal y, also ist Ihr Selectim Wesentlichen nur ein foreach- schreiben Sie es als solches.
Pavel Minaev
Ich habe dies nicht als gute Lösung vorgeschlagen. OP wollte etwas interessanteres als foreach.
Larsenal
Ja, aber zu missbrauchen , Selectwie foreachgeht vorbei „interessant“ und in, na ja, „Missbrauch“. Ein interessanter Ansatz wäre hier die Verwendung Enumerable.Aggregatemit StringBuilderals Startwert - versuchen.
Pavel
Gute Idee. Ich muss aussteigen, aber ich kann dem einen Wirbel geben.
Larsenal
0

Sie können die System.Linq-Bibliothek verwenden. Es ist effizienter:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
Maurico Bello
quelle