it-swarm.com.de

Wie verbinde ich int [] mit einer durch Zeichen getrennten Zeichenfolge in .NET?

Ich habe eine Reihe von ganzen Zahlen:

int[] number = new int[] { 2,3,6,7 };

Was ist der einfachste Weg, diese in eine einzelne Zeichenkette umzuwandeln, bei der die Zahlen durch ein Zeichen getrennt sind (wie: "2,3,6,7")?

Ich bin in C # und .NET 3.5.

98
Riri
var ints = new int[] {1, 2, 3, 4, 5};
var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());
Console.WriteLine(result); // prints "1,2,3,4,5"

EDIT : Ab (mindestens) .NET 4.5

var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());

ist äquivalent zu:

var result = string.Join(",", ints);

EDIT :

Ich sehe mehrere Lösungen, die für die Verwendung von StringBuilder werben. Jemand beschwert sich, dass die Join-Methode ein IEnumerable-Argument verwenden sollte.

Ich werde dich enttäuschen :) String.Join benötigt Array aus einem einzigen Grund - Leistung. Die Join-Methode muss die Größe der Daten kennen, um die erforderliche Speichermenge effektiv vorab zuweisen zu können.

Hier ist ein Teil der internen Implementierung der String.Join-Methode:

// length computed from length of items in input array and length of separator
string str = FastAllocateString(length);
fixed (char* chRef = &str.m_firstChar) // note than we use direct memory access here
{
    UnSafeCharBuffer buffer = new UnSafeCharBuffer(chRef, length);
    buffer.AppendString(value[startIndex]);
    for (int j = startIndex + 1; j <= num2; j++)
    {
        buffer.AppendString(separator);
        buffer.AppendString(value[j]);
    }
}

Ich bin zu faul, um die Leistung der vorgeschlagenen Methoden zu vergleichen. Aber irgendwas sagt mir, dass Join gewinnen wird :)

159
aku

Obwohl das OP .NET 3.5 spezifizierte, können Benutzer, die dies in .NET 2.0 mit C # 2 tun möchten, dies tun:

string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));

Ich finde, es gibt eine Reihe anderer Fälle, in denen die Verwendung der Convert.xxx-Funktionen eine bessere Alternative zu einem Lambda darstellt, obwohl das Lambda in C # 3 möglicherweise die Typinferenz unterstützt.

Eine ziemlich kompakte C # 3-Version, die mit .NET 2.0 funktioniert, ist folgende:

string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
32
Will Dean

Eine Mischung der beiden Ansätze wäre, eine Erweiterungsmethode für IEnumerable <T> zu schreiben, die einen StringBuilder verwendet. Hier ist ein Beispiel mit verschiedenen Überladungen, je nachdem, ob Sie die Umwandlung angeben oder sich nur auf einfachen ToString verlassen möchten. Ich habe die Methode "JoinStrings" anstelle von "Join" genannt, um Verwechslungen mit der anderen Art von Join zu vermeiden. Vielleicht kann sich jemand einen besseren Namen einfallen lassen :)

using System;
using System.Collections.Generic;
using System.Text;

public static class Extensions
{
    public static string JoinStrings<T>(this IEnumerable<T> source, 
                                        Func<T, string> projection, string separator)
    {
        StringBuilder builder = new StringBuilder();
        bool first = true;
        foreach (T element in source)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                builder.Append(separator);
            }
            builder.Append(projection(element));
        }
        return builder.ToString();
    }

    public static string JoinStrings<T>(this IEnumerable<T> source, string separator)
    {
        return JoinStrings(source, t => t.ToString(), separator);
    }
}

class Test
{

    public static void Main()
    {
        int[] x = {1, 2, 3, 4, 5, 10, 11};

        Console.WriteLine(x.JoinStrings(";"));
        Console.WriteLine(x.JoinStrings(i => i.ToString("X"), ","));
    }
}
11
Jon Skeet
String.Join(";", number.Select(item => item.ToString()).ToArray());

Wir müssen jedes der Elemente in ein String konvertieren, bevor wir sie verbinden können. Daher ist es sinnvoll, Select und einen Lambda-Ausdruck zu verwenden. Dies entspricht in einigen anderen Sprachen map. Dann müssen wir die resultierende Auflistung von Strings zurück in ein Array konvertieren, da String.Join Nur ein String-Array akzeptiert.

Die ToArray() ist meiner Meinung nach etwas hässlich. String.Join Sollte wirklich IEnumerable<String> Akzeptieren, es gibt keinen Grund, es auf nur Arrays zu beschränken. Dies liegt wahrscheinlich nur daran, dass Join aus früheren Generika stammt, als Arrays die einzige Art von typisierter Sammlung waren.

8
JacquesB

Wenn Ihr Array von Ganzzahlen groß sein kann, erzielen Sie mit einem StringBuilder eine bessere Leistung. Z.B.:

StringBuilder builder = new StringBuilder();
char separator = ',';
foreach(int value in integerArray)
{
    if (builder.Length > 0) builder.Append(separator);
    builder.Append(value);
}
string result = builder.ToString();

Bearbeiten: Als ich dies gepostet habe, hatte ich den irrtümlichen Eindruck, dass "StringBuilder.Append (int value)" es intern geschafft hat, die Zeichenfolgendarstellung des ganzzahligen Werts anzuhängen, ohne ein Zeichenfolgenobjekt zu erstellen. Dies ist falsch: Wenn Sie die Methode mit Reflector untersuchen, wird lediglich value.ToString () angehängt.

Daher besteht der einzige mögliche Leistungsunterschied darin, dass diese Technik die Erstellung eines Arrays vermeidet und die Zeichenfolgen etwas früher für die Garbage Collection freigibt. In der Praxis macht dies keinen messbaren Unterschied, daher habe ich diese bessere Lösung gewählt.

5
Joe

Die Frage ist nach "der einfachsten Möglichkeit, diese in eine einzelne Zeichenfolge umzuwandeln, bei der die Zahlen durch ein Zeichen getrennt sind".

Der einfachste Weg ist:

int[] numbers = new int[] { 2,3,6,7 };
string number_string = string.Join(",", numbers);
// do whatever you want with your exciting new number string

BEARBEITEN: Dies funktioniert nur in .NET 4.0 und höher. Ich habe die .NET 3.5-Anforderung verpasst, als ich die Frage zum ersten Mal las.

5
WebMasterP

In .NET 4.0 hat der String-Join eine Überladung für params object[], so einfach ist das:

int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);

beispiel

int[] ids = new int[] { 1, 2, 3 };
System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)");
cmd.CommandText = cmd.CommandText.Replace("@bla",  string.Join(",", ids));

In .NET 2.0 ist es ein bisschen schwieriger, da es keine solche Überlastung gibt. Sie benötigen also Ihre eigene generische Methode:

public static string JoinArray<T>(string separator, T[] inputTypeArray)
{
    string strRetValue = null;
    System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

    for (int i = 0; i < inputTypeArray.Length; ++i)
    {
        string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

        if (!string.IsNullOrEmpty(str))
        { 
            // SQL-Escape
            // if (typeof(T) == typeof(string))
            //    str = str.Replace("'", "''");

            ls.Add(str);
        } // End if (!string.IsNullOrEmpty(str))

    } // Next i 

    strRetValue= string.Join(separator, ls.ToArray());
    ls.Clear();
    ls = null;

    return strRetValue;
}

In .NET 3.5 können Sie Erweiterungsmethoden verwenden:

public static class ArrayEx
{

    public static string JoinArray<T>(this T[] inputTypeArray, string separator)
    {
        string strRetValue = null;
        System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

        for (int i = 0; i < inputTypeArray.Length; ++i)
        {
            string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

            if (!string.IsNullOrEmpty(str))
            { 
                // SQL-Escape
                // if (typeof(T) == typeof(string))
                //    str = str.Replace("'", "''");

                ls.Add(str);
            } // End if (!string.IsNullOrEmpty(str))

        } // Next i 

        strRetValue= string.Join(separator, ls.ToArray());
        ls.Clear();
        ls = null;

        return strRetValue;
    }

}

Sie können also die JoinArray-Erweiterungsmethode verwenden.

int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");

Sie können diese Erweiterungsmethode auch in .NET 2.0 verwenden, wenn Sie Ihrem Code das ExtensionAttribute hinzufügen:

// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}
2
Stefan Steiger

Ich stimme dem Lambda-Ausdruck für Lesbarkeit und Wartbarkeit zu, aber es wird nicht immer die beste Option sein. Der Nachteil der beiden Methoden IEnumerable/ToArray und StringBuilder besteht darin, dass sie eine Liste mit Elementen oder Zeichen dynamisch vergrößern müssen, da sie nicht wissen, wie viel Platz für die endgültige Zeichenfolge benötigt wird.

Wenn in seltenen Fällen Geschwindigkeit wichtiger ist als Prägnanz, ist Folgendes effizienter.

int[] number = new int[] { 1, 2, 3, 4, 5 };
string[] strings = new string[number.Length];
for (int i = 0; i < number.Length; i++)
  strings[i] = number[i].ToString();
string result = string.Join(",", strings);
2
DocMax
ints.Aggregate("", ( str, n ) => str +","+ n ).Substring(1);

Ich dachte auch, dass es einen einfacheren Weg gibt. Sie wissen nichts über Leistung, hat jemand eine (theoretische) Idee?

2
void

Du kannst tun

ints.ToString(",")
ints.ToString("|")
ints.ToString(":")

Auschecken

Separator Delimited ToString für Array, List, Dictionary, Generic IEnumerable

1
Ray Lu