string.Join on a List <int> or other type


86

Voglio trasformare un array o un elenco di int in una stringa delimitata da virgole, come questa:

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

Ma string.Join accetta solo List<string>come secondo parametro. Qual è il modo migliore per farlo?


2
Quale versione di C # / .NET stai usando?
Mark Byers

Risposte:


149

Il modo migliore è aggiornare a .NET 4.0 dove c'è un sovraccarico che fa quello che vuoi:

Se non puoi eseguire l'aggiornamento, puoi ottenere lo stesso effetto usando Select e ToArray.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());

Presuppone inoltre che sia almeno su C # 3, .NET 3.5
Anthony Pegram

Perché usare LINQ invece del ToArraymetodo integrato di List<T>?
Steven Sudit

2
perché avrebbe una lista <int>. La selezione di linq converte List <int> in IEnumerable <string> e quindi nell'array.
Greg Bogumil

L'aggiornamento a 4.0 non è pratico nella mia situazione, ma la soluzione LINQ è esattamente quello che stavo cercando. Grazie!
Code Commander

1
@gbogumil: Scusa, non ho notato che era un file int.
Steven Sudit

5

Un scalabile e sicura implementazione di una stringa enumerabile generica unirsi per .NET 3.5. L'utilizzo degli iteratori è in modo che il valore della stringa di join non sia bloccato alla fine della stringa. Funziona correttamente con 0, 1 e più elementi:

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

Utilizzo:

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

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

Godere!


+1: questo è il mio metodo preferito prima di .NET 4.0. Molto più scalabile rispetto alla produzione di un array completamente nuovo di stringhe da un elenco di int in modo che String.Join(String, String[])possa essere chiamato. L'unica cosa che direi è che è insolito vedere questo metodo scritto come un'estensione Stringrispetto a IEnumerable<String>: tendo a chiamarlo sempre alla fine di una lunga catena di chiamate al metodo di estensione.
Alex Humphrey

2
Ho rubato l'idea da Python se questo è d'aiuto!
Soppresso il

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
Un buon approccio 2.0. Potresti voler rendere il carattere di unione un parametro piuttosto che codificarlo nel metodo.
Anthony Pegram

Una tipica ottimizzazione è quella di aggiungere il delimitatore senza test, quindi rimuovere l'ultimo carattere una volta uscito dal ciclo.
Steven Sudit

@Steven - Ci stavo pensando, ma penso che questo dipenderebbe anche dalla lunghezza della stringa (senza test non sono sicuro), quindi sono rimasto fedele al semplice controllo bool.
Kyle Rosendo

Sospetto che l'ottimizzazione sarebbe misurabile solo per stringhe lunghe. Detto questo, non credo che sarebbe più lento anche per quelli brevi.
Steven Sudit

3

Avevo un metodo di estensione simile che ho modificato a questo

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

e lo usi in questo modo

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

.NET 3.5


Non sono sicuro che mi piaccia. IEnumerable<T>ha già un Joinmetodo e questo nuovo metodo esegue un'operazione completamente diversa, rendendo il suo utilizzo controintuitivo. In secondo luogo, se si stesse andando a creare questo metodo, andare avanti e fare genericamente applicabile.
Anthony Pegram

È un trucco che imita il metodo di join sugli array in Ruby. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström

Inoltre .ToString () non restituisce sempre una rappresentazione di stringa di T, quindi immagino che potrebbe davvero causare un po 'di confusione.
Jonas Elfström

2

Questa risposta è per te se non vuoi ancora avventurarti nelle profondità di .NET 4.0.

String.Join () concatena tutti gli elementi di un array di stringhe, utilizzando il separatore specificato tra ogni elemento.

La sintassi è

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

Piuttosto che passare la tua lista di int al metodo Join, suggerisco di creare prima un array di stringhe.

Ecco cosa propongo:

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
Questo è un approccio decente se qualcuno è ancora su 2.0. Tuttavia, intArraynon è necessario. List<int>è indicizzabile e ha una Countproprietà, rendendo superflua la conversione in un array. Potresti anche voler rendere il carattere di unione un parametro piuttosto che codificarlo nel metodo.
Anthony Pegram

2

Utilizzando .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

In .NET la classe list ha un .ToArray()metodo. Qualcosa del genere potrebbe funzionare:

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

Rif: List <T> Metodi (MSDN)


Questo answer from 2010già afferma che, come ToStringè implicito quando si esegue un file string.Join.
Miller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.