Jak połączyć dwie tablice w języku C #?

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

Teraz używam

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

Czy istnieje łatwiejsza lub bardziej wydajna metoda?

hwiechers
źródło
8
Co rozumiesz przez „wydajny”? Kod jest wystarczająco krótki, więc zakładam, że masz na myśli wydajność pod względem procesora / pamięci RAM?
TToni,
4
Nie, szybki rzut oka na Reflector pokazuje, że używa bufora podwójnego zapełnienia
erikkallen,
Tylko jasne, że potrzebuję z, aby być typu int [].
hwiechers
4
Tak naprawdę nie martwię się o wydajność. (Powiedziałem, że łatwiej lub wydajniej.) Zadałem pytanie, aby sprawdzić, jak inni ludzie wykonują to wspólne zadanie.
hwiechers

Odpowiedzi:

331
var z = new int[x.Length + y.Length];
x.CopyTo(z, 0);
y.CopyTo(z, x.Length);
Zed
źródło
8
@manthrax -> W swojej obronie C # ma tendencję do faworyzowania list, które są znacznie potężniejsze niż tablice. Wydaje się, że jedynym funkcjonalnym celem używania tablic są wywołania Interop (Unmanaged C ++).
Levi Fuller
@LeviFuller Innym miejscem, w którym C # używa tablicy, są parametry o zmiennej liczbie params.
ChrisW
1
@LeviFuller - dziwne, że wiele procedur systemowych zwraca tablice zamiast list. np. System.IO.Directory.GetFiles()zwraca tablicę ciągów.
orion elenzil
4
To nie jest dziwne. Tablica jest niezmienna, lista nie jest. Lista również wykorzystuje więcej pamięci niż tablica, chyba że wywoływana jest funkcja TrimExcess (co nie zdarza się w ToList)
CSharpie
1
Również tablica jest szybsza niż lista podczas uzyskiwania dostępu do danych, ponieważ lista po prostu otacza tablicę i ma narzut związany z wywoływaniem indeksatora.
C0DEF52
84

Spróbuj tego:

List<int> list = new List<int>();
list.AddRange(x);
list.AddRange(y);
int[] z = list.ToArray();
Adriaan Stander
źródło
5
Lub nawetList<int> list = new List<int>(x);
Matthew Scharley,
7
W jaki sposób jest to bardziej wydajne niż x.Concat (y)? Działa i wszystko, tylko się zastanawiam, czy jest coś, co czyni to lepszym?
Mike Two
7
możesz zrobić pierwszą linię List <int> list = new List <int> (x.Length + y.Length); Aby uniknąć zmiany rozmiaru, która może się zdarzyć, gdy zadzwonisz do AddRange
Mike Two
5
@Mathew Scharley. Pytanie dotyczy bardziej wydajnego rozwiązania. Wiem, że tytuł sprawia, że ​​brzmi to jak każda stara kombinacja, ale pełne pytanie wykracza poza to. Czytając niektóre odpowiedzi Czuję, że niektórzy ludzie odpowiadają na tytuł. Pomyślałem więc, że ta odpowiedź powinna prawdopodobnie zawierać wzmiankę o wydajności, jeśli zasługuje na poparcie, ponieważ wydaje się, że o to właśnie chodzi.
Mike Two
2
okazuje się, że AddRange jest w rzeczywistości dość kosztownym procesem, więc pierwszą odpowiedzią na tym forum powinno być preferowane podejście: dotnetperls.com/insertrange
Liam
49

Możesz napisać metodę rozszerzenia:

public static T[] Concat<T>(this T[] x, T[] y)
{
    if (x == null) throw new ArgumentNullException("x");
    if (y == null) throw new ArgumentNullException("y");
    int oldLen = x.Length;
    Array.Resize<T>(ref x, x.Length + y.Length);
    Array.Copy(y, 0, x, oldLen, y.Length);
    return x;
}

Następnie:

int[] x = {1,2,3}, y = {4,5};
int[] z = x.Concat(y); // {1,2,3,4,5}
Marc Gravell
źródło
1
Czy nie istnieje już metoda rozszerzenia, która działa na dowolnym IEnumerable?
Mike Two
2
Tak, i korzystałbym z tego w większości przypadków. Ale mają wiele kosztów ogólnych. To zależy; 98% czasu koszty ogólne są w porządku. Jeśli jednak jesteś w 2%, to przydatna jest bezpośrednia praca memcopy / tablic.
Marc Gravell
1
@nawfal, jak to jest Copyszybsze niż CopyTo? Możesz rozwinąć temat?
skrebbel
1
@skrebbel mine była niedokładnym komentarzem. W tym czasie przeszedłem testy i znalazłem Copy szybciej. Ale teraz wydaje się, że są po prostu równi. Wówczas mogłem odkryć, że ogólnie podejście Marca jest bardziej wydajne, ponieważ przekazuje tę samą instancję z powrotem, podczas gdy w podejściu Zeda tworzy nową tablicę. Przepraszam :)
nawfal
1
@Shimmy To nie byłoby. Wewnątrz tej metody x jest tylko zmienną lokalną, przekazanie x jako odniesienie do metody zmiany rozmiaru utworzy nową tablicę i zmieni (zmienną lokalną) x, aby na nią wskazać. Lub przeformułować: x przekazane do zmiany rozmiaru i x wewnątrz metody rozszerzenia jest tą samą zmienną, ale x nie jest przekazany do metody rozszerzenia jako ref, więc x jest inną zmienną niż zmienna w zakresie, z którego to rozszerzenie zostało wywołane .
AnorZaken,
40

Zdecydowałem się na bardziej ogólne rozwiązanie, które pozwala łączyć dowolny zestaw jednowymiarowych tablic tego samego typu. (Łączyłem 3+ na raz.)

Moja funkcja:

    public static T[] ConcatArrays<T>(params T[][] list)
    {
        var result = new T[list.Sum(a => a.Length)];
        int offset = 0;
        for (int x = 0; x < list.Length; x++)
        {
            list[x].CopyTo(result, offset);
            offset += list[x].Length;
        }
        return result;
    }

I użycie:

        int[] a = new int[] { 1, 2, 3 };
        int[] b = new int[] { 4, 5, 6 };
        int[] c = new int[] { 7, 8 };
        var y = ConcatArrays(a, b, c); //Results in int[] {1,2,3,4,5,6,7,8}
deepee1
źródło
Fajna funkcja, dzięki! Zmieniono params T[][]na, this T[][]aby było to rozszerzenie.
Mark
Cześć wszystkim, ta funkcja wygląda na to, czego szukałem, ale masz pomysł, jak to osiągnąć? link @Mark
George B
31

To jest to:

using System.Linq;

int[] array1 = { 1, 3, 5 };
int[] array2 = { 0, 2, 4 };

// Concatenate array1 and array2.
var result1 = array1.Concat(array2);
Roland
źródło
4
Masz na myśli, int[] result = array1.ToList().Concat(array2.ToList()).toArray();że nie możesz nakładać Concat bezpośrednio na tablice
Michail Michailidis
4
To rozwiązanie - z = x.Concat (y) - wspomniano w pierwotnym pytaniu powyżej.
Jon Schneider,
1
To co się dzieje beztoArray() Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
Tibor Udvari
2
To nie jest bezpośrednia odpowiedź. PO poprosił int[] result = ?, jesteś ukrywanie problemu odpowiedź za swoim varIN że wynik będzie IEnumerable<int>nie int[]. (jeden z powodów, dla których nie lubię varzwrotów metod)
David S.
2
Ta metoda jest używana w pytaniu, więc ta odpowiedź nie zawiera żadnych nowych informacji, a bez .ToArray()wywołania ten kod nie zwróci faktycznej tablicy, więc jest to również niepoprawna odpowiedź.
Mani Gandham,
10

Możesz usunąć wywołanie ToArray () z końca. Czy istnieje powód, dla którego musisz być tablicą po wywołaniu Concat?

Wywołanie Concat tworzy iterator dla obu tablic. Nie tworzy nowej tablicy, więc nie użyłeś więcej pamięci dla nowej tablicy. Kiedy wywołujesz ToArray, faktycznie tworzysz nową tablicę i zajmujesz pamięć dla nowej tablicy.

Więc jeśli potrzebujesz po prostu iterować obie, po prostu zadzwoń do Concat.

Mike Two
źródło
8

Wiem, że OP był tylko lekko ciekawy wydajności. Większe tablice mogą uzyskać inny wynik (patrz @kurdishTree). I że zwykle nie ma to znaczenia (@ jordan.peoples). Niemniej jednak byłem ciekawy i dlatego straciłem zmysły (jak wyjaśniał @TigerShark) .... Mam na myśli, że napisałem prosty test oparty na pierwotnym pytaniu ... i wszystkich odpowiedziach ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace concat
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] x = new int [] { 1, 2, 3};
            int[] y = new int [] { 4, 5 };


            int itter = 50000;
            Console.WriteLine("test iterations: {0}", itter);

            DateTime startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                int[] z;
                z = x.Concat(y).ToArray();
            }
            Console.WriteLine ("Concat Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks );

            startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                var vz = new int[x.Length + y.Length];
                x.CopyTo(vz, 0);
                y.CopyTo(vz, x.Length);
            }
            Console.WriteLine ("CopyTo Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks );

            startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                List<int> list = new List<int>();
                list.AddRange(x);
                list.AddRange(y);
                int[] z = list.ToArray();
            }
            Console.WriteLine("list.AddRange Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.Concat(x, y);
            }
            Console.WriteLine("Concat(x, y) Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArrays(x, y);
            }
            Console.WriteLine("ConcatArrays Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.SSConcat(x, y);
            }
            Console.WriteLine("SSConcat Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int k = 0; k < itter; k++)
            {
                int[] three = new int[x.Length + y.Length];

                int idx = 0;

                for (int i = 0; i < x.Length; i++)
                    three[idx++] = x[i];
                for (int j = 0; j < y.Length; j++)
                    three[idx++] = y[j];
            }
            Console.WriteLine("Roll your own Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);


            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArraysLinq(x, y);
            }
            Console.WriteLine("ConcatArraysLinq Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArraysLambda(x, y);
            }
            Console.WriteLine("ConcatArraysLambda Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                List<int> targetList = new List<int>(x);
                targetList.Concat(y);
            }
            Console.WriteLine("targetList.Concat(y) Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] result = x.ToList().Concat(y.ToList()).ToArray();
            }
            Console.WriteLine("x.ToList().Concat(y.ToList()).ToArray() Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);
        }
    }
    static class Methods
    {
        public static T[] Concat<T>(this T[] x, T[] y)
        {
            if (x == null) throw new ArgumentNullException("x");
            if (y == null) throw new ArgumentNullException("y");
            int oldLen = x.Length;
            Array.Resize<T>(ref x, x.Length + y.Length);
            Array.Copy(y, 0, x, oldLen, y.Length);
            return x;
        }

        public static T[] ConcatArrays<T>(params T[][] list)
        {
            var result = new T[list.Sum(a => a.Length)];
            int offset = 0;
            for (int x = 0; x < list.Length; x++)
            {
                list[x].CopyTo(result, offset);
                offset += list[x].Length;
            }
            return result;
        }


        public static T[] SSConcat<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;
        }

        public static T[] ConcatArraysLinq<T>(params T[][] arrays)
        {
            return (from array in arrays
                    from arr in array
                    select arr).ToArray();
        }

        public static T[] ConcatArraysLambda<T>(params T[][] arrays)
        {
            return arrays.SelectMany(array => array.Select(arr => arr)).ToArray();
        }
    }

}

Wynik był:

wprowadź opis zdjęcia tutaj

Rzuć własne wygrane.

połączyć się
źródło
Zgodnie z metodami, które stosowały metody, Metody prawdopodobnie dodały około 10 000 tyknięć w moim systemie.
amalgamat
1
Uruchomiłem Twój kod w Visual Studio 2013 w trybie wydania i stwierdziłem, że jeśli testowana tablica nie jest tak mała jak Twoja (jak 1000 elementów), CopyTobędzie pierwsza i ~ 3 razy szybsza niż Roll your own.
Pan Ree,
@ Mr.Ree Tak, moja tablica była naprawdę mała, prawda? Dzięki. Byłbym zainteresowany, aby zobaczyć, czy Block block działa jeszcze lepiej ...
połącz
7

Uważaj na tę Concatmetodę. Łączenie po tablicy macierzy w C # wyjaśnia, że:

var z = x.Concat(y).ToArray();

Będzie nieefektywny w przypadku dużych tablic. Oznacza to, że Concatmetoda dotyczy tylko tablic wielkości meduim (do 10000 elementów).

kurdishTree
źródło
2
Co należy zrobić z tablicami zawierającymi ponad 10 000 elementów?
alex
6
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;
}
Sergey Shteyn
źródło
2
W StackOverflow nie tylko wklejaj kod, ale także wyjaśnij swoje podejście. W tym konkretnym przypadku być może będziesz musiał wyjaśnić, co twoja późna odpowiedź dodaje do odpowiedzi już udzielonych (i zaakceptowanych)
Gert Arnold
1
Nie jestem pewien, co to „to” robi przed pierwszym paramem, ale dla reszty jest to doskonała funkcja. Ogólny i z nieskończoną ilością parametrów.
Nyerguds
2
Cześć Nyerguds. Aby odpowiedzieć na twoje pytanie, słowo kluczowe „this” służy do uczynienia tej funkcji metodą rozszerzenia. Aby uzyskać więcej informacji na temat metod rozszerzenia, zapoznaj się z tym artykułem MSDN
JFish222,
6

Bardziej wydajne (szybsze) do wykorzystania Buffer.BlockCopyw ciągu Array.CopyTo,

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

int[] z = new int[x.Length + y.Length];
var byteIndex = x.Length * sizeof(int);
Buffer.BlockCopy(x, 0, z, 0, byteIndex);
Buffer.BlockCopy(y, 0, z, byteIndex, y.Length * sizeof(int));

Napisałem prosty program testowy, który „rozgrzewa Jittera”, skompilowany w trybie wydania i uruchomił go bez dołączonego debugera na moim komputerze.

Dla 10 000 000 powtórzeń przykładu z pytania

Concat zajął 3088ms

Kopiowanie zajęło 1079 ms

BlockCopy zajęło 603 ms

Jeśli zmienię tablice testowe na dwie sekwencje od 0 do 99, otrzymam wyniki podobne do tego,

Concat zajął 45945 ms

Kopiowanie zajęło 2230 ms

BlockCopy zajęło 1689 ms

Na podstawie tych wyników mogę stwierdzić, że metody CopyToi BlockCopysą znacznie bardziej wydajne niż, Concata ponadto, jeśli wydajność jest celem, BlockCopyma przewagę nad CopyTo.

Aby odpowiedzieć na to pytanie, jeśli wydajność nie ma znaczenia lub będzie kilka iteracji, wybierz metodę, która jest dla ciebie najłatwiejsza. Buffer.BlockCopyoferuje pewne narzędzie do konwersji typów poza zakres tego pytania.

Jodrell
źródło
6

Spóźniona odpowiedź :-).

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

    }
Saleh Saeednia
źródło
3

Najbardziej wydajną strukturą pod względem pamięci RAM (i procesora) do przechowywania połączonej tablicy byłaby specjalna klasa, która implementuje IEnumerable (lub jeśli chcesz nawet wywodzi się z Array) i łączy wewnętrznie z oryginalnymi tablicami w celu odczytania wartości. AFAIK Concat właśnie to robi.

W przykładowym kodzie można pominąć .ToArray (), co zwiększyłoby jego wydajność.

TToni
źródło
3

Przykro mi, aby ożywić stary wątek, ale co z tym:

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

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

Następnie w kodzie:

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[]

Dopóki nie zadzwonisz .ToArray(), .ToList()lub .ToDictionary(...)pamięć nie zostanie przydzielona, ​​możesz „zbudować zapytanie” i albo zadzwonić do jednego z tych trzech, aby je wykonać, lub po prostu przejrzeć je wszystkie, używając foreach (var i in z){...}klauzuli, która zwraca element na raz z yield return t;powyżej...

Powyższą funkcję można przekształcić w rozszerzenie w następujący sposób:

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

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

Więc w kodzie możesz zrobić coś takiego:

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[]

Reszta jest taka sama jak poprzednio.

Kolejnym ulepszeniem tego byłoby przekształcenie się T[]w IEnumerable<T>(tak params T[][]by się stało params IEnumerable<T>[]), aby te funkcje akceptowały więcej niż tylko tablice.

Mam nadzieję że to pomoże.

Nurchi
źródło
2

Możesz to zrobić tak, jak to określiłeś, lub jeśli chcesz uzyskać naprawdę ręczną instrukcję, możesz stworzyć własną pętlę:

        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];
dreadwail
źródło
@nawfal Myślę, że będzie to zależeć od wielkości tablicy. To wygrało mój test na małą tablicę.
amalgamat
2

Znalazłem eleganckie jedno liniowe rozwiązanie wykorzystujące wyrażenie LINQ lub Lambda , oba działają tak samo (LINQ jest konwertowany na Lambda podczas kompilacji programu). Rozwiązanie działa dla dowolnego typu tablicy i dla dowolnej liczby tablic.

Za pomocą LINQ:

public static T[] ConcatArraysLinq<T>(params T[][] arrays)
{
    return (from array in arrays
            from arr in array
            select arr).ToArray();
}

Korzystanie z Lambda:

public static T[] ConcatArraysLambda<T>(params T[][] arrays)
{
    return arrays.SelectMany(array => array.Select(arr => arr)).ToArray();
}

Oba zapewniłem dla swoich preferencji. Pod względem wydajności rozwiązania @Sergey Shteyn lub @ deepee1 są nieco szybsze, a wyrażenie Lambda jest najwolniejsze. Czas potrzebny zależy od typu elementów tablicy, ale jeśli nie ma milionów wywołań, nie ma znaczącej różnicy między metodami.

Marko Grešak
źródło
1

Należy pamiętać, że podczas korzystania z LINQ korzystasz z opóźnionego wykonania. Wszystkie inne opisane tutaj metody działają doskonale, ale są wykonywane natychmiast. Ponadto funkcja Concat () jest prawdopodobnie zoptymalizowana w taki sposób, że nie można tego zrobić samodzielnie (wywołania wewnętrznych interfejsów API, wywołania systemu operacyjnego itp.). W każdym razie, chyba że naprawdę musisz spróbować zoptymalizować, jesteś obecnie na dobrej drodze do „źródła wszelkiego zła”;)

Siewers
źródło
1

Spróbuj wykonać następujące czynności:

T[] r1 = new T[size1];
T[] r2 = new T[size2];

List<T> targetList = new List<T>(r1);
targetList.Concat(r2);
T[] targetArray = targetList.ToArray();
کی‌راد عباسی
źródło
1

Oto moja odpowiedź:

int[] z = new List<string>()
    .Concat(a)
    .Concat(b)
    .Concat(c)
    .ToArray();

Tej metody można użyć na poziomie inicjalizacji, na przykład w celu zdefiniowania statycznego konkatenacji tablic statycznych:

public static int[] a = new int [] { 1, 2, 3, 4, 5 };
public static int[] b = new int [] { 6, 7, 8 };
public static int[] c = new int [] { 9, 10 };

public static int[] z = new List<string>()
    .Concat(a)
    .Concat(b)
    .Concat(c)
    .ToArray();

Zawiera jednak dwa zastrzeżenia, które należy wziąć pod uwagę:

  • Concat Metoda tworzy iterator nad obu tablicach: nie tworzy nową tablicę, będąc w ten sposób efektywny pod względem pamięci używane: jednak późniejsze  ToArray  będą negować taką zaletę, ponieważ będzie on rzeczywiście stworzyć nową tablicę i zajmują pamięć dla nowa tablica.
  • Jak powiedział @Jodrell, Concatbyłoby raczej nieefektywne w przypadku dużych tablic: powinno się go stosować tylko w przypadku tablic średnich.

Jeśli dążenie do wydajności jest koniecznością, zamiast tego można zastosować następującą metodę:

/// <summary>
/// Concatenates two or more arrays into a single one.
/// </summary>
public static T[] Concat<T>(params T[][] arrays)
{
    // return (from array in arrays from arr in array select arr).ToArray();

    var result = new T[arrays.Sum(a => a.Length)];
    int offset = 0;
    for (int x = 0; x < arrays.Length; x++)
    {
        arrays[x].CopyTo(result, offset);
        offset += arrays[x].Length;
    }
    return result;
}

Lub (dla fanów One-Liner):

int[] z = (from arrays in new[] { a, b, c } from arr in arrays select arr).ToArray();

Chociaż ta druga metoda jest znacznie bardziej elegancka, ta druga jest zdecydowanie lepsza pod względem wydajności.

Aby uzyskać dodatkowe informacje, zapoznaj się z tym postem na moim blogu.

Darkseal
źródło
0

Dla int [] to, co zrobiłeś, wygląda dla mnie dobrze. Odpowiedź osoby postronnej również by się sprawdziła List<int>.

mezoid
źródło
2
Concat działałby również dla List <int>. To jest świetne w Concat, działa na każdym IEnumerable <>
Mike Two
0

Dla mniejszych tablic <10000 elementów:

using System.Linq;

int firstArray = {5,4,2};
int secondArray = {3,2,1};

int[] result = firstArray.ToList().Concat(secondArray.ToList()).toArray();
Michail Michailidis
źródło
dlaczego warto korzystać z Linq, kiedy nie trzeba ?!
ina
0
static class Extensions
{
    public static T[] Concat<T>(this T[] array1, params T[] array2) => ConcatArray(array1, array2);

    public static T[] ConcatArray<T>(params T[][] arrays)
    {
        int l, i;

        for (l = i = 0; i < arrays.Length; l += arrays[i].Length, i++);

        var a = new T[l];

        for (l = i = 0; i < arrays.Length; l += arrays[i].Length, i++)
            arrays[i].CopyTo(a, l);

        return a;
    }
}

Myślę, że powyższe rozwiązanie jest bardziej ogólne i lżejsze niż inne, które tu widziałem. Jest bardziej ogólny, ponieważ nie ogranicza konkatenacji tylko dla dwóch tablic i jest lżejszy, ponieważ nie używa LINQ ani Listy.

Zwróć uwagę, że rozwiązanie jest zwięzłe, a dodana ogólność nie powoduje znaczącego obciążenia środowiska wykonawczego.

drowa
źródło
Radziłbym spróbować znaleźć nowe pytania lub te, które nie mają jeszcze wielu odpowiedzi - w tym takich jak twoje.
Andrew Barber
Zaproponowałem to rozwiązanie, ponieważ myślę, że podsumowuje to, co dobre od innych. Zostało wykonane.
drowa
-2

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

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

Milad Doraki
źródło
2
Unionnie jest to bardzo dobry sposób, aby to zrobić, ponieważ domyślnie wywołuje Distincti usuwa wszelkie duplikaty z połączonej kolekcji. Concatjest znacznie lepszy, ale jest już w pierwotnym pytaniu.
nurchi
-3
int[] scores = { 100, 90, 90, 80, 75, 60 };
int[] alice = { 50, 65, 77, 90, 102 };
int[] scoreBoard = new int[scores.Length + alice.Length];

int j = 0;
for (int i=0;i<(scores.Length+alice.Length);i++)  // to combine two arrays
{
    if(i<scores.Length)
    {
        scoreBoard[i] = scores[i];
    }
    else
    {
        scoreBoard[i] = alice[j];
        j = j + 1;

    }
}


for (int l = 0; l < (scores.Length + alice.Length); l++)
{
    Console.WriteLine(scoreBoard[l]);
}
presty prajna
źródło