366 Stimmen

Wie kann ich zwei Arrays in C# verketten?

int[] x = new int [] { 1, 2, 3};
int[] y = new int [] { 4, 5 };

int[] z = // your answer here...

Debug.Assert(z.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));

Zurzeit verwende ich

int[] z = x.Concat(y).ToArray();

Gibt es eine einfachere oder effizientere Methode?

8voto

Saleh Saeednia Punkte 91

Späte Antwort :-).

public static class ArrayExtention
    {

        public static T[] Concatenate<T>(this T[] array1, T[] array2)
        {
            T[] result = new T[array1.Length + array2.Length];
            array1.CopyTo(result, 0);
            array2.CopyTo(result, array1.Length);
            return result;
        }

    }

6voto

Sergey Shteyn Punkte 61
public static T[] Concat<T>(this T[] first, params T[][] arrays)
{
    int length = first.Length;
    foreach (T[] array in arrays)
    {
        length += array.Length;
    }
    T[] result = new T[length];
    length = first.Length;
    Array.Copy(first, 0, result, 0, first.Length);
    foreach (T[] array in arrays)
    {
        Array.Copy(array, 0, result, length, array.Length);
        length += array.Length;
    }
    return result;
}

3voto

TToni Punkte 8755

Die effizienteste Struktur in Bezug auf RAM (und CPU), um das kombinierte Array zu halten wäre eine spezielle Klasse, die IEnumerable implementiert (oder wenn Sie möchten, sogar von Array abgeleitet) und Links intern zu den ursprünglichen Arrays, um die Werte zu lesen. AFAIK Concat tut genau das.

In Ihrem Beispielcode könnten Sie die Funktion .ToArray() allerdings weglassen, was die Effizienz erhöhen würde.

3voto

nurchi Punkte 720

Entschuldigung, dass ich ein altes Thema wieder aufgreife, aber wie wäre es damit:

static IEnumerable<T> Merge<T>(params T[][] arrays)
{
    var merged = arrays.SelectMany(arr => arr);

    foreach (var t in merged)
        yield return t;
}

Dann in Ihrem Code:

int[] x={1, 2, 3};
int[] y={4, 5, 6};

var z=Merge(x, y);  // 'z' is IEnumerable<T>

var za=z.ToArray(); // 'za' is int[]

Bis Sie anrufen .ToArray() , .ToList() , oder .ToDictionary(...) wird der Speicher nicht zugewiesen, können Sie Ihre Abfrage erstellen und entweder eine dieser drei Abfragen aufrufen, um sie auszuführen, oder einfach alle Abfragen durchgehen, indem Sie foreach (var i in z){...} Klausel, die jeweils ein Element aus der yield return t; oben...

Die obige Funktion kann wie folgt in eine Erweiterung umgewandelt werden:

static IEnumerable<T> Merge<T>(this T[] array1, T[] array2)
{
    var merged = array1.Concat(array2);

    foreach (var t in merged)
        yield return t;
}

Im Code können Sie also etwas tun wie:

int[] x1={1, 2, 3};
int[] x2={4, 5, 6};
int[] x3={7, 8};

var z=x1.Merge(x2).Merge(x3);   // 'z' is IEnumerable<T>

var za=z.ToArray(); // 'za' is int[]

Der Rest ist derselbe wie zuvor.

Eine weitere Verbesserung wäre die Änderung T[] in IEnumerable<T> (also die params T[][] werden würde params IEnumerable<T>[] ), damit diese Funktionen mehr als nur Arrays akzeptieren.

Ich hoffe, das hilft.

2voto

dreadwail Punkte 14502

Sie können es so machen, wie Sie es beschrieben haben, oder Sie können Ihre eigene Schleife drehen, wenn Sie es wirklich manuell machen wollen:

string[] one = new string[] { "a", "b" };
string[] two = new string[] { "c", "d" };
string[] three;

three = new string[one.Length + two.Length];

int idx = 0;

for (int i = 0; i < one.Length; i++)
    three[idx++] = one[i];
for (int j = 0; j < two.Length; j++)
    three[idx++] = two[j];

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X