string.Join auf einer Liste <int> oder einem anderen Typ

86

Ich möchte ein Array oder eine Liste von Ints in eine durch Kommas getrennte Zeichenfolge umwandeln, wie folgt:

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

String.Join ist jedoch nur List<string>der zweite Parameter. Was ist der beste Weg, dies zu tun?

Code Commander
quelle
2
Welche Version von C # / .NET verwenden Sie?
Mark Byers
Mögliches Duplikat von stackoverflow.com/questions/3211422/…
goodeye

Antworten:

148

Der beste Weg ist ein Upgrade auf .NET 4.0, bei dem eine Überlastung vorliegt, die genau das tut, was Sie möchten:

Wenn Sie kein Upgrade durchführen können, können Sie mit Select und ToArray denselben Effekt erzielen.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());
Mark Byers
quelle
Nimmt auch an, dass er mindestens auf C # 3, .NET 3.5
Anthony Pegram
Warum LINQ anstelle der integrierten ToArrayMethode von verwenden List<T>?
Steven Sudit
2
weil er eine Liste <int> haben würde. Die linq-Auswahl konvertiert die Liste <int> in IEnumerable <string> und dann in das Array.
Greg Bogumil
Ein Upgrade auf 4.0 ist in meiner Situation nicht praktikabel, aber die LINQ-Lösung ist genau das, wonach ich gesucht habe. Vielen Dank!
Code Commander
1
@gbogumil: Sorry, habe nicht bemerkt, dass es ein war int.
Steven Sudit
5

Eine skalierbare und sichere Implementierung eines generischen Enumerable-String-Joins für .NET 3.5. Die Verwendung von Iteratoren ist so, dass der Wert der Verknüpfungszeichenfolge nicht am Ende der Zeichenfolge hängen bleibt. Es funktioniert korrekt mit 0, 1 und mehr Elementen:

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

Verwendung:

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

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

Genießen!

Gelöscht
quelle
+1: Dies ist mein bevorzugter Weg vor .NET 4.0. Viel skalierbarer als das Erstellen eines völlig neuen Arrays von Zeichenfolgen aus einer Liste von Ints, damit String.Join(String, String[])diese aufgerufen werden können. Das einzige, was ich sagen würde, ist, dass es ungewöhnlich ist, diese Methode als Erweiterung zu sehen, Stringim Gegensatz zu IEnumerable<String>- ich nenne sie immer am Ende einer langen Kette von Erweiterungsmethodenaufrufen.
Alex Humphrey
2
Ich habe Python die Idee gestohlen, wenn das Hilfe ist!
Gelöscht
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
quelle
2
Ein guter 2.0-Ansatz. Möglicherweise möchten Sie das Verknüpfungszeichen zu einem Parameter machen, anstatt es fest in die Methode zu codieren.
Anthony Pegram
Eine typische Optimierung besteht darin, das Trennzeichen ohne Test anzuhängen und dann das letzte Zeichen zu entfernen, sobald Sie die Schleife verlassen.
Steven Sudit
@Steven - Ich habe darüber nachgedacht, aber ich denke, dies würde auch von der Länge der Zeichenfolge abhängen (ohne zu testen, bin ich mir nicht sicher), also habe ich mich an die einfache Bool-Prüfung gehalten.
Kyle Rosendo
Ich vermute, dass die Optimierung nur für lange Saiten messbar wäre. Trotzdem denke ich nicht, dass es auch für kurze langsamer sein würde.
Steven Sudit
2

Diese Antwort ist für Sie, wenn Sie sich noch nicht in die Tiefen von .NET 4.0 wagen möchten.

String.Join () verkettet alle Elemente eines String-Arrays unter Verwendung des angegebenen Trennzeichens zwischen den einzelnen Elementen.

Die Syntax lautet

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

Anstatt Ihre Liste der Ints an die Join-Methode zu übergeben, empfehle ich, zuerst ein Array von Zeichenfolgen aufzubauen.

Folgendes schlage ich vor:

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
quelle
3
Dies ist ein anständiger Ansatz, wenn jemand noch auf 2.0 ist. Ist intArrayjedoch nicht erforderlich. List<int>ist indizierbar und hat eine CountEigenschaft, wodurch die Konvertierung in ein Array überflüssig wird. Möglicherweise möchten Sie das Verknüpfungszeichen auch zu einem Parameter machen, anstatt es fest in die Methode zu codieren.
Anthony Pegram
2

Hatte eine ähnliche Erweiterungsmethode, die ich daran geändert habe

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

und du benutzt es so

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

.NET 3.5

Jonas Elfström
quelle
Ich bin mir nicht sicher, ob mir das gefällt. IEnumerable<T>hat bereits eine JoinMethode, und diese neue Methode führt eine völlig andere Operation aus, wodurch ihre Verwendung nicht intuitiv ist. Zweitens, wenn Sie wurden mit dieser Methode erstellen gehen, gehen Sie vor und machen es allgemein anwendbar.
Anthony Pegram
Es ist ein Hack, der die Join-Methode für Arrays in Ruby nachahmt. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström
Außerdem gibt .ToString () nicht immer eine Zeichenfolgendarstellung von T zurück, daher könnte dies zu Verwirrung führen.
Jonas Elfström
2

Verwenden von .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
quelle
2

In .NET verfügt die Listenklasse über eine .ToArray()Methode. So etwas könnte funktionieren:

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

Ref: List <T> Methods (MSDN)

Winter
quelle
Dies answer from 2010besagt bereits, dass, wie ToStringbei a string.Join.
Miller