Conversion d'une liste <int> en une chaîne séparée par des virgules


116

Existe-t-il un moyen de prendre une liste et de la convertir en une chaîne séparée par des virgules?

Je sais que je peux juste faire une boucle et le construire, mais je pense que certains d'entre vous sont une façon plus cool de le faire?

Je veux vraiment apprendre ces types de «trucs», alors veuillez expliquer ou créer un lien vers la documentation sur la méthode que vous utilisez.

Réponses:


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

7
Intelligent mais lent et gonflé, car il alloue une chaîne par élément. L'utilisation d'un StringBuilder serait beaucoup plus efficace.
Steven Sudit

3
D'après ce que j'ai vu en ligne (recherche rapide), String.Join est plus rapide que d'utiliser un StringBuilder.
Yuriy Faktorovich


6
Je pense que Steven fait référence à la partie n.ToString () plutôt qu'à String.Join.
Larsenal

9
Larsenal: mais StringBuilder.Append (Int32) appelle quand même ToString sur l'entier. StringBuilder n'évite pas comme par magie le coût d'allocation d'une chaîne pour chaque élément; il le range juste bien hors de vue.
itowlson

115

La solution simple est

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

Je l'ai utilisé tout à l'heure dans mon code, fonctionnant de manière funtastique.


1
Remercier! c'est une belle approche
Irfan Ashraf

2
C'est une meilleure approche que la réponse acceptée. Avec cette approche, vous n'avez pas besoin d'importer Linq et c'est plus rapide.
JoKeRxbLaCk

Cool! Je n'ai jamais connu string.Join a des surcharges génériques. Merci.
mrmashal le

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

Parfait si vous ne pouvez pas utiliser .NET 4
Greg Woods

6

Pour environ un milliard de solutions à une version légèrement plus compliquée de ce problème - dont beaucoup sont lentes, boguées ou ne se compilent même pas - voir les commentaires de mon article sur ce sujet:

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

et le commentaire StackOverflow:

Le défi d'Eric Lippert "ergoter par la virgule", meilleure réponse?


Merci pour le lien. Ce problème de concaténation de chaînes s'est avéré plus complexe et plus éducatif que je ne m'y attendais!
Steven Sudit

4

Pour plus de fraîcheur, je ferais de cette méthode une extension sur IEnumerable <T> afin qu'elle fonctionne sur n'importe quel IEnumerable:

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

Utilisez-le comme suit:

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

Deux optimisations possibles: 1) Ajoutez le délimiteur après chaque élément, puis supprimez le délimiteur après la fin de la boucle. 2) Spécifiez une capacité pour le StringBuilder.
Steven Sudit

1
Si vous creusez Reflector, il s'avère que Join additionne les longueurs pour précalculer la taille du tampon, et "amorce également la pompe" en ajoutant la première chaîne à l'extérieur de la boucle, puis, à l'intérieur de la boucle, en ajoutant sans condition le délimiteur avant le chaîne suivante. Combiné avec quelques astuces non sûres / internes, cela devrait être très rapide.
Steven Sudit

@Steven: a suivi vos conseils.
cdiggins

1
Vous codez en dur le délimiteur dans votre extension et ignorez la valeur transmise pour un délimiteur et avez manqué le point-virgule. Ça devrait êtrereturn string.Join(delim, self);
Andrew

1

Cela semble raisonnablement rapide.

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

Mon entrée "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));

Je n'ai simplement pas compris comment ajouter conditionnellement la virgule.


1
Veuillez ne pas écrire Selectavec des effets secondaires dans le lambda. Dans ce cas, vous n'utilisez même pas y, donc vous n'êtes Selectessentiellement qu'un foreach- alors écrivez-le comme tel.
Pavel Minaev

Je ne suggérais pas cela comme une bonne solution. OP voulait quelque chose de plus intéressant que foreach.
Larsenal

Ouais, mais abuser Selectcomme foreachça passe "intéressant" et dans, eh bien, "abuser". Une approche plus intéressante ici serait d'utiliser Enumerable.Aggregateavec StringBuildercomme valeur de départ - essayez cela.
Pavel Minaev

Bonne idée. Je dois sortir, mais je peux donner un tourbillon.
Larsenal

0

vous pouvez utiliser, la bibliothèque System.Linq; C'est plus efficace:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.