string.Join sur une liste <int> ou un autre type

86

Je veux transformer un tableau ou une liste d'entiers en une chaîne délimitée par des virgules, comme ceci:

string myFunction(List<int> a) {
    return string.Join(",", a);
}

Mais string.Join ne prend List<string>que le deuxième paramètre. Quelle est la meilleure façon de procéder?

Commandant du code
la source
2
Quelle version de C # / .NET utilisez-vous?
Mark Byers
Copie

Réponses:

149

Le meilleur moyen est de passer à .NET 4.0 là où il y a une surcharge qui fait ce que vous voulez:

Si vous ne pouvez pas mettre à niveau, vous pouvez obtenir le même effet en utilisant Select et ToArray.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());
Mark Byers
la source
Suppose également qu'il soit au moins sur C # 3, .NET 3.5
Anthony Pegram
Pourquoi utiliser LINQ au lieu de la ToArrayméthode intégrée de List<T>?
Steven Sudit
2
car il aurait une liste <int>. La sélection linq convertit le List <int> en IEnumerable <string>, puis en tableau.
Greg Bogumil
La mise à niveau vers 4.0 n'est pas pratique dans ma situation, mais la solution LINQ est exactement ce que je recherchais. Merci!
Code Commander
1
@gbogumil: Désolé, je n'ai pas remarqué que c'était un int.
Steven Sudit
5

Une implémentation évolutive et sûre d'une jointure de chaîne énumérable générique pour .NET 3.5. L'utilisation des itérateurs est telle que la valeur de la chaîne de jointure ne soit pas bloquée à la fin de la chaîne. Cela fonctionne correctement avec 0, 1 et plus d'éléments:

public static class StringExtensions
{
    public static string Join<T>(this string joinWith, IEnumerable<T> list)
    {
        if (list == null)
            throw new ArgumentNullException("list");
        if (joinWith == null)
            throw new ArgumentNullException("joinWith");

        var stringBuilder = new StringBuilder();
        var enumerator = list.GetEnumerator();

        if (!enumerator.MoveNext())
            return string.Empty;

        while (true)
        {
            stringBuilder.Append(enumerator.Current);
            if (!enumerator.MoveNext())
                break;

            stringBuilder.Append(joinWith);
        }

        return stringBuilder.ToString();
    }
}

Usage:

var arrayOfInts = new[] { 1, 2, 3, 4 };
Console.WriteLine(",".Join(arrayOfInts));

var listOfInts = new List<int> { 1, 2, 3, 4 };
Console.WriteLine(",".Join(listOfInts));

Prendre plaisir!

Supprimé
la source
+1: C'est ma méthode préférée avant .NET 4.0. Beaucoup plus évolutif que de produire un tout nouveau tableau de chaînes à partir d'une liste d'entiers pour String.Join(String, String[])pouvoir être appelé. La seule chose que je dirais, c'est qu'il est inhabituel de voir cette méthode écrite comme une extension Stringpar opposition à IEnumerable<String>- j'ai tendance à toujours l'appeler à la fin d'une longue chaîne d'appels de méthode d'extension.
Alex Humphrey
2
J'ai volé l'idée à Python si cela m'aide!
Supprimé
4

.NET 2.0:

static string IntListToDelimitedString(List<int> intList, char Delimiter)
{
    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < intList.Count; i++)
    {
        builder.Append(intList[i].ToString());

        if (i != intList.Count - 1)
            builder.Append(Delimiter);
    }

    return builder.ToString();
}
Kyle Rosendo
la source
3
Une bonne approche 2.0. Vous souhaiterez peut-être faire du caractère de jointure un paramètre plutôt que de le coder en dur dans la méthode.
Anthony Pegram
Une optimisation typique consiste à ajouter le délimiteur sans test, puis à supprimer le dernier caractère une fois que vous êtes sorti de la boucle.
Steven Sudit
@Steven - J'y pensais, mais je pense que cela dépendrait aussi de la longueur de la chaîne (sans tester, je ne suis pas sûr), alors je me suis contenté de la simple vérification des booléens.
Kyle Rosendo
Je soupçonne que l'optimisation ne serait mesurable que pour les longues chaînes. Cela dit, je ne pense pas que ce serait plus lent pour les plus petits.
Steven Sudit
3

J'avais une méthode d'extension similaire que j'ai modifiée pour cela

public static class MyExtensions
{
    public static string Join(this List<int> a, string splitChar)
    {
        return string.Join(splitChar, a.Select(n => n.ToString()).ToArray());
    }
}

et vous l'utilisez comme ça

var test = new List<int>() { 1, 2, 3, 4, 5 };
string s = test.Join(",");

.NET 3.5

Jonas Elfström
la source
Pas sûr que j'aime ça. IEnumerable<T>a déjà une Joinméthode, et cette nouvelle méthode effectue une opération complètement différente, rendant son utilisation contre-intuitive. En second lieu , si vous étiez allez créer cette méthode, allez - y et de le rendre applicable génériquement.
Anthony Pegram
C'est un hack imitant la méthode de jointure sur des tableaux dans Ruby. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström
De plus .ToString () ne renvoie pas toujours une représentation sous forme de chaîne de T, donc je suppose que cela pourrait vraiment semer la confusion.
Jonas Elfström
2

Cette réponse est faite pour vous si vous ne voulez pas encore vous aventurer dans les profondeurs de .NET 4.0.

String.Join () concatène tous les éléments d'un tableau de chaînes, en utilisant le séparateur spécifié entre chaque élément.

La syntaxe est

public static string Join(
    string separator,
    params string[] value
)

Plutôt que de passer votre liste d'entiers à la méthode Join, je suggère de créer d'abord un tableau de chaînes.

Voici ce que je propose:

static string myFunction(List<int> a) {
    int[] intArray = a.ToArray();
    string[] stringArray = new string[intArray.Length];

    for (int i = 0; i < intArray.Length; i++)
    {
        stringArray[i] = intArray[i].ToString();
    }

    return string.Join(",", stringArray);
}
Greg
la source
3
C'est une approche décente si quelqu'un est toujours sur 2.0. Cependant, ce intArrayn'est pas nécessaire. List<int>est indexable et possède une Countpropriété, rendant la conversion en tableau superflue. Vous pouvez également faire du caractère de jointure un paramètre plutôt que de le coder en dur dans la méthode.
Anthony Pegram
2

Utilisation de .NET 4.0

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string s = myFunction(PopulateTestList());
        this.TextBox1.Text = s;
    }

    protected List<int> PopulateTestList()
    {
        List<int> thisList = new List<int>();
        thisList.Add(22);
        thisList.Add(33);
        thisList.Add(44);

        return thisList;
    }

    protected string myFunction(List<int> a)
    {
        return string.Join(",", a);
    }
}
user436001
la source
2

Dans .NET, la classe de liste a une .ToArray()méthode. Quelque chose comme ça pourrait fonctionner:

string myFunction(List<int> a)
{
    return string.Join(",", a.ToArray());
}

Réf: méthodes List <T> (MSDN)

wintoch
la source
Cela answer from 2010indique déjà que, comme cela ToStringest sous-entendu lors de l'exécution d'un fichier string.Join.
Miller