it-swarm.com.de

int Array zu String

In C # habe ich ein Array von Ints, das nur Ziffern enthält. Ich möchte dieses Array in einen String konvertieren.

Array-Beispiel: 

int[] arr = {0,1,2,3,0,1};

Wie kann ich dies in eine Zeichenfolge konvertieren, die wie folgt formatiert ist: "012301"?

50
user397232

at.net 3.5 verwenden:

 String.Join("", new List<int>(array).ConvertAll(i => i.ToString()).ToArray());

verwenden Sie at.net 4.0 oder höher:

 string result = string.Join("", array);
81
JSBձոգչ

Sie können einfach String.Join function verwenden und als Trennzeichen string.Empty verwenden, da StringBuilder intern verwendet wird.

string result = string.Join(string.Emtpy, new []{0,1,2,3,0,1});

Beispiel: Wenn Sie ein Semikolon als Trennzeichen verwenden, lautet das Ergebnis 0;1;2;3;0;1. Es funktioniert tatsächlich mit einem Null-Trennzeichen, und der zweite Parameter kann für alle Objekte wie folgt aufgelistet werden:

string result = string.Join(null, new object[]{0,1,2,3,0,"A",DateTime.Now});
27
Jan Remunda

Ich weiß, dass meine Meinung wahrscheinlich nicht die populärste ist, aber ich denke, es fällt mir schwer, auf den Linq-y-Bandwagen zu springen. Es ist schick. Es ist verdichtet. Ich verstehe das und bin nicht dagegen, es dort zu verwenden, wo es angebracht ist. Vielleicht liegt es nur an mir, aber ich habe das Gefühl, dass die Menschen nicht mehr daran denken, Hilfsfunktionen zu erstellen, um das zu erreichen, was sie wollen, und stattdessen lieber ihren Code mit (manchmal) übermäßig langen Zeilen von Linq-Code zu streuen, um einen dichten 1-Liner zu erstellen.

Ich sage nicht, dass eine der Antworten von Linq, die die Leute hier zur Verfügung gestellt haben, schlecht ist, aber ich denke, es besteht das Potenzial, dass diese einzelnen Codezeilen länger und dunkler werden können, wenn Sie mit verschiedenen Situationen umgehen müssen . Was ist, wenn Ihr Array null ist? Was ist, wenn Sie eine begrenzte Zeichenfolge anstatt nur eine reine Verkettung wünschen? Was ist, wenn einige der Ganzzahlen in Ihrem Array zweistellig sind und Sie jeden Wert mit führenden Nullen auffüllen möchten, sodass die Zeichenfolge für jedes Element die gleiche Länge hat wie der Rest?

Nehmen Sie eine der angegebenen Antworten als Beispiel:

        result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString());

Wenn ich mir Sorgen machen muss, dass das Array leer ist, wird es jetzt wie folgt:

        result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString());

Wenn ich eine durch Kommas getrennte Zeichenfolge haben möchte, wird diese wie folgt:

        result = (arr == null) ? null : arr.Skip(1).Aggregate(arr[0].ToString(), (s, i) => s + "," + i.ToString());

Dies ist immer noch nicht so schlimm, aber ich denke, es ist nicht auf einen Blick ersichtlich, was diese Codezeile tut.

Natürlich hindert Sie nichts daran, diese Codezeile in Ihre eigene Utility-Funktion zu werfen, so dass Sie nicht so lange in Ihre Anwendungslogik eingemischt werden, vor allem, wenn Sie es an mehreren Stellen tun:

    public static string ToStringLinqy<T>(this T[] array, string delimiter)
    {
        // edit: let's replace this with a "better" version using a StringBuilder
        //return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(array[0].ToString(), (s, i) => s + "," + i.ToString());
        return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(new StringBuilder(array[0].ToString()), (s, i) => s.Append(delimiter).Append(i), s => s.ToString());
    }

Aber wenn Sie es trotzdem in eine Utility-Funktion einbauen wollen, müssen Sie es wirklich zu einem 1-Liner verdichten? In diesem Fall sollten Sie der Klarheit halber nicht ein paar zusätzliche Zeilen hinzufügen und einen StringBuilder nutzen, um keine wiederholten Verkettungen durchzuführen:

    public static string ToStringNonLinqy<T>(this T[] array, string delimiter)
    {
        if (array != null)
        {
            // edit: replaced my previous implementation to use StringBuilder
            if (array.Length > 0)
            {
                StringBuilder builder = new StringBuilder();

                builder.Append(array[0]);
                for (int i = 1; i < array.Length; i++)
                {
                    builder.Append(delimiter);
                    builder.Append(array[i]);
                }

                return builder.ToString()
            }
            else
            {
                return string.Empty;
            }
        }
        else
        {
            return null;
        }
    }

Und wenn Sie sich wirklich so sehr um die Leistung sorgen, können Sie diese Funktion sogar in eine Hybridfunktion umwandeln, die entscheidet, ob Sie string ausführen möchten. Fügen Sie einen StringBuilder hinzu oder verwenden Sie einen StringBuilder, je nachdem, wie viele Elemente sich im Array befinden. meiner Meinung nach nicht wert und möglicherweise mehr schädlich als nützlich, aber ich benutze es als Beispiel für dieses Problem):

    public static string ToString<T>(this T[] array, string delimiter)
    {
        if (array != null)
        {
            // determine if the length of the array is greater than the performance threshold for using a stringbuilder
            // 10 is just an arbitrary threshold value I've chosen
            if (array.Length < 10)
            {
                // assumption is that for arrays of less than 10 elements
                // this code would be more efficient than a StringBuilder.
                // Note: this is a crazy/pointless micro-optimization.  Don't do this.
                string[] values = new string[array.Length];

                for (int i = 0; i < values.Length; i++)
                    values[i] = array[i].ToString();

                return string.Join(delimiter, values);
            }
            else
            {
                // for arrays of length 10 or longer, use a StringBuilder
                StringBuilder sb = new StringBuilder();

                sb.Append(array[0]);
                for (int i = 1; i < array.Length; i++)
                {
                    sb.Append(delimiter);
                    sb.Append(array[i]);
                }

                return sb.ToString();
            }
        }
        else
        {
            return null;
        }
    }

In diesem Beispiel ist die Auswirkung auf die Leistung wahrscheinlich nicht der Mühe wert, aber der Punkt ist, wenn Sie sich in einer Situation befinden, in der Sie sich tatsächlich mit der Leistung Ihrer Vorgänge befassen müssen, was auch immer sie sind, dann wird dies höchstwahrscheinlich der Fall sein Es ist einfacher und lesbarer, dies innerhalb einer Utility-Funktion zu handhaben als mit einem komplexen Linq-Ausdruck.

Diese Utility-Funktion sieht immer noch ziemlich klobig aus. Lassen Sie uns nun den hybriden Kram aufgeben und folgendes tun:

    // convert an enumeration of one type into an enumeration of another type
    public static IEnumerable<TOut> Convert<TIn, TOut>(this IEnumerable<TIn> input, Func<TIn, TOut> conversion)
    {
        foreach (TIn value in input)
        {
            yield return conversion(value);
        }
    }

    // concatenate the strings in an enumeration separated by the specified delimiter
    public static string Delimit<T>(this IEnumerable<T> input, string delimiter)
    {
        IEnumerator<T> enumerator = input.GetEnumerator();

        if (enumerator.MoveNext())
        {
            StringBuilder builder = new StringBuilder();

            // start off with the first element
            builder.Append(enumerator.Current);

            // append the remaining elements separated by the delimiter
            while (enumerator.MoveNext())
            {
                builder.Append(delimiter);
                builder.Append(enumerator.Current);
            }

            return builder.ToString();
        }
        else
        {
            return string.Empty;
        }
    }

    // concatenate all elements
    public static string ToString<T>(this IEnumerable<T> input)
    {
        return ToString(input, string.Empty);
    }

    // concatenate all elements separated by a delimiter
    public static string ToString<T>(this IEnumerable<T> input, string delimiter)
    {
        return input.Delimit(delimiter);
    }

    // concatenate all elements, each one left-padded to a minimum length
    public static string ToString<T>(this IEnumerable<T> input, int minLength, char paddingChar)
    {
        return input.Convert(i => i.ToString().PadLeft(minLength, paddingChar)).Delimit(string.Empty);
    }

Jetzt haben wir separate und ziemlich kompakte Dienstfunktionen, von denen jede für sich selbst nützlich sein kann.

Letztendlich möchte ich nicht sagen, dass Sie Linq nicht verwenden sollten, sondern einfach sagen, vergessen Sie nicht die Vorteile der Erstellung Ihrer eigenen Hilfsfunktionen, selbst wenn sie klein sind und möglicherweise nur eine einzige Zeile enthalten, aus der das Ergebnis zurückgegeben wird eine Zeile Linq-Code. Nicht zuletzt können Sie Ihren Anwendungscode noch kompakter halten, als dies mit einer Linq-Codezeile möglich wäre. Wenn Sie ihn an mehreren Stellen verwenden, erleichtert die Verwendung einer Utility-Funktion die Anpassung Ihrer Ausgabe falls Sie es später ändern müssen.

Für dieses Problem schreibe ich einfach so etwas in meinen Anwendungscode:

        int[] arr = { 0, 1, 2, 3, 0, 1 };

        // 012301
        result = arr.ToString<int>();

        // comma-separated values
        // 0,1,2,3,0,1
        result = arr.ToString(",");

        // left-padded to 2 digits
        // 000102030001
        result = arr.ToString(2, '0');
24

Um die Erstellung eines zusätzlichen Arrays zu vermeiden, können Sie Folgendes tun.

var builder = new StringBuilder();
Array.ForEach(arr, x => builder.Append(x));
var res = builder.ToString();
20
JaredPar
string result = arr.Aggregate("", (s, i) => s + i.ToString());

(Haftungsausschluss: Wenn Sie viele Ziffern (mindestens Hunderte) haben und Wert auf Leistung legen, schlage ich vor, auf diese Methode zu verzichten und eine StringBuilder zu verwenden, wie in der Antwort von JaredPar.)

9
mquander

Du kannst tun:

 int[] arr = {0,1,2,3,0,1};
 string results = string.Join("",arr.Select(i => i.ToString()).ToArray());

Das gibt dir deine Ergebnisse.

5
Reed Copsey

Ich mag es, StringBuilder mit Aggregate() zu verwenden. Der "Trick" ist, dass Append() die StringBuilder-Instanz selbst zurückgibt: 

var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) );
var result = sb.ToString();     
5
Danko Durbić

Ich habe das hier der Nachwelt überlassen, empfehle es aber nicht, da es nicht sehr lesbar ist. Dies gilt insbesondere jetzt, nachdem ich zurückgekommen bin, um zu sehen, ob ich nach einiger Zeit nachgedacht habe, was ich dachte, als ich es schrieb. .)

string s = string.Concat(arr.Cast<object>().ToArray());
1
Paul Ruane
string.Join("", (from i in arr select i.ToString()).ToArray())

In .NET 4.0 kann der string.Join einen IEnumerable<string> direkt verwenden:

string.Join("", from i in arr select i.ToString())
1
Michael Damatov

Der effizienteste Weg ist, nicht jedes int in einen String zu konvertieren, sondern einen String aus einem Array von Zeichen zu erstellen. Dann hat der Garbage Collector nur ein neues temporäres Objekt, um das er sich kümmern muss.

int[] arr = {0,1,2,3,0,1};
string result = new string(Array.ConvertAll<int,char>(arr, x => Convert.ToChar(x + '0')));
1

Wenn dies ein langes Array ist, können Sie es verwenden

var sb = arr.Aggregate(new StringBuilder(), ( s, i ) => s.Append( i ), s.ToString());
0
Dzior