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?


2
Quelle version de C # / .NET utilisez-vous?
Mark Byers

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

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!


+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();
}

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


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

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

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)


Cela answer from 2010indique déjà que, comme cela ToStringest sous-entendu lors de l'exécution d'un fichier string.Join.
Miller
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.