Bagaimana cara menggabungkan dua array di 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 }));

Saat ini saya menggunakan

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

Apakah ada metode yang lebih mudah atau lebih efisien?

penambang
sumber
8
Apa yang Anda maksud dengan "efisien"? Kode ini cukup pendek, jadi saya anggap Anda maksud efisien dalam hal CPU / RAM?
TToni
4
Tidak, pandangan cepat dengan Reflector menunjukkan bahwa ia menggunakan buffer double-when-full
erikkallen
Cukup jelas saya perlu z untuk menjadi tipe int [].
hwiechers
4
Saya tidak terlalu memperhatikan efisiensi. (Saya memang mengatakan lebih mudah atau lebih efisien.) Saya mengajukan pertanyaan untuk memeriksa bagaimana orang lain menangani tugas bersama ini.
hwiechers

Jawaban:

331
var z = new int[x.Length + y.Length];
x.CopyTo(z, 0);
y.CopyTo(z, x.Length);
Zed
sumber
8
@manthrax -> Dalam pembelaannya, C # cenderung menyukai daftar yang jauh lebih kuat daripada array. Tampaknya satu-satunya tujuan fungsional untuk menggunakan array adalah untuk panggilan Interop (Unmanaged C ++).
Levi Fuller
@LeviFuller Tempat lain di mana C # menggunakan array adalah dengan paramsparameter nomor variabel .
ChrisW
1
@LeviFuller - aneh bahwa banyak sistem rutin mengembalikan array daripada daftar. mis. System.IO.Directory.GetFiles()mengembalikan array string.
orion elenzil
4
Ini tidak aneh. Array tidak dapat diubah, daftar tidak. Juga sebuah Daftar menggunakan lebih banyak memori daripada sebuah array, kecuali jika TrimExcess disebut (yang tidak terjadi di ToList)
CSharpie
1
Juga array lebih cepat daripada daftar ketika mengakses data, karena daftar hanya membungkus array di dalam dan memiliki overhead untuk memanggil pengindeks.
C0DEF52
84

Coba ini:

List<int> list = new List<int>();
list.AddRange(x);
list.AddRange(y);
int[] z = list.ToArray();
Adriaan Stander
sumber
5
Atau bahkanList<int> list = new List<int>(x);
Matthew Scharley
7
Bagaimana itu lebih efisien daripada x.Compat (y)? Berhasil dan semua, saya hanya ingin tahu apakah ada sesuatu yang membuatnya lebih baik?
Mike Two
7
Anda mungkin ingin membuat Daftar baris pertama <int> daftar = Daftar baru <int> (x.Length + y.Length); Untuk menghindari perubahan ukuran yang mungkin terjadi saat Anda menelepon AddRange
Mike Two
5
@Mathew Scharley. Pertanyaannya adalah meminta solusi yang lebih efisien. Saya tahu judulnya membuatnya terdengar seperti kombinasi lama yang akan dilakukan tetapi pertanyaan lengkap melampaui itu. Membaca beberapa jawaban saya hanya merasa beberapa orang menjawab judul. Jadi saya berpikir bahwa jawaban ini mungkin harus menyebutkan efisiensi jika layak mendapatkan upvotes karena itu tampaknya menjadi titik pertanyaan.
Mike Two
2
ternyata AddRange sebenarnya proses yang cukup mahal, jadi jawaban pertama di forum ini harus menjadi pendekatan yang disukai: dotnetperls.com/insertrange
Liam
49

Anda dapat menulis metode ekstensi:

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

Kemudian:

int[] x = {1,2,3}, y = {4,5};
int[] z = x.Concat(y); // {1,2,3,4,5}
Marc Gravell
sumber
1
Bukankah sudah ada metode ekstensi yang berfungsi pada IEnumerable?
Mike Two
2
Ya, dan saya akan menggunakannya dengan senang hati untuk sebagian besar kasus. Tetapi mereka memiliki banyak overhead. Tergantung; 98% dari waktu biaya overhead baik-baik saja. Jika Anda berada di 2%, maka, beberapa pekerjaan memcopy / array langsung berguna.
Marc Gravell
1
@nawfal, bagaimana Copylebih cepat dari CopyTo? Mau menguraikan?
skrebbel
1
@skrebbel milik saya adalah komentar yang tidak akurat. Saya melakukan beberapa pengujian saat itu dan saya menemukan Salin lebih cepat. Tapi sekarang tampaknya mereka sama. Apa yang mungkin saya temukan saat itu adalah bahwa secara keseluruhan pendekatan Marc lebih efisien karena ia melewati contoh yang sama saat dalam pendekatan Zed ia menciptakan array baru. Permintaan maaf :)
nawfal
1
@ Kimmy Tidak akan. Di dalam metode ini x hanyalah variabel lokal, meneruskan x sebagai referensi ke metode mengubah ukuran akan membuat array baru dan mengubah (variabel lokal) x untuk menunjuk ke sana. Atau untuk mengulangi: x dilewatkan ke dalam resize dan x di dalam metode ekstensi adalah variabel yang sama, tetapi x tidak diteruskan ke metode ekstensi sebagai ref, jadi x adalah variabel yang berbeda dari variabel dalam lingkup ekstensi ini dipanggil dari .
AnorZaken
40

Saya memilih solusi tujuan umum yang memungkinkan menggabungkan serangkaian array satu dimensi dari tipe yang sama. (Saya menggabungkan 3+ sekaligus.)

Fungsi saya:

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

Dan penggunaan:

        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
sumber
Fungsi bagus, terima kasih! Berubah params T[][]untuk this T[][]untuk membuatnya perpanjangan.
Tandai
Hai teman-teman, fungsi ini terlihat seperti apa yang saya cari tetapi saya tahu bagaimana saya bisa mencapai ini? tautan @Mark
George B
31

Ini dia:

using System.Linq;

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

// Concatenate array1 and array2.
var result1 = array1.Concat(array2);
Roland
sumber
4
Maksud int[] result = array1.ToList().Concat(array2.ToList()).toArray();Anda, Anda tidak dapat menerapkan Concat pada array secara langsung, saya yakin
Michail Michailidis
4
Solusi ini - z = x.Concat (y) - disebutkan dalam pertanyaan asli di atas.
Jon Schneider
1
Inilah yang terjadi tanpatoArray() Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
Tibor Udvari
2
Ini bukan jawaban langsung. OP bertanya int[] result = ?, Anda menyembunyikan masalah jawaban Anda vardi belakang bahwa hasil Anda akan IEnumerable<int>, bukan int[]. (salah satu alasan mengapa saya tidak suka varpada metode pengembalian)
David S.
2
Metode ini adalah apa yang digunakan dalam pertanyaan sehingga jawaban ini tidak memberikan info baru, dan tanpa .ToArray()panggilan, kode ini tidak akan mengembalikan array yang sebenarnya sehingga juga merupakan jawaban yang salah.
Mani Gandham
10

Anda dapat menerima panggilan ToArray () dari ujung. Apakah ada alasan Anda membutuhkannya menjadi array setelah panggilan ke Concat?

Calling Concat menciptakan iterator pada kedua array. Itu tidak membuat array baru sehingga Anda belum menggunakan lebih banyak memori untuk array baru. Ketika Anda memanggil ToArray, Anda benar-benar membuat array baru dan mengambil memori untuk array baru.

Jadi jika Anda hanya perlu dengan mudah beralih ke keduanya maka cukup hubungi Concat.

Mike Two
sumber
8

Saya tahu OP hanya sedikit ingin tahu tentang kinerja. Array yang lebih besar itu mungkin mendapatkan hasil yang berbeda (lihat @urdishTree). Dan itu biasanya tidak masalah (@ jordan.peoples). Tidak kurang, saya penasaran dan karena itu kehilangan akal (seperti @TigerShark menjelaskan) .... Maksud saya, saya menulis tes sederhana berdasarkan pertanyaan awal .... dan semua jawaban ....

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

}

Hasilnya adalah:

masukkan deskripsi gambar di sini

Gulung kemenangan Anda sendiri.

menggabungkan
sumber
Dalam keadilan untuk metode yang menggunakan metode, Metode mungkin menambahkan sekitar 10.000 kutu pada sistem saya.
amalgamate
1
Saya menjalankan kode Anda di visual studio 2013 dalam mode rilis dan menemukan bahwa, jika array yang diuji tidak sekecil milik Anda (seperti 1000 elemen), CopyToakan menjadi yang paling cepat dan ~ 3x lebih cepat daripada Roll your own.
Tn. Ree
@ Mr.Ree Ya, array saya benar-benar kecil bukan. Terima kasih. Akan tertarik untuk melihat apakah Block copy lebih baik ...
amalgamate
7

Hati-hati dengan Concatmetodenya. Posting Array Concatenation dalam C # menjelaskan bahwa:

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

Akan tidak efisien untuk array besar. Itu berarti Concatmetode ini hanya untuk array berukuran meduim (hingga 10.000 elemen).

kurdishTree
sumber
2
Apa yang harus dilakukan dengan array yang berisi lebih dari 10.000 elemen?
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
sumber
2
Di StackOverflow tolong jangan hanya menempelkan kode, tetapi juga jelaskan pendekatan Anda. Dalam kasus khusus ini, Anda mungkin juga harus menjelaskan apa jawaban Anda yang terlambat ditambahkan ke jawaban yang sudah diberikan (dan diterima)
Gert Arnold
1
Tidak yakin apa yang "ini" lakukan sebelum param pertama, tetapi untuk sisanya, ini adalah fungsi yang sangat baik. Umum, dan dengan jumlah parameter yang tak terbatas.
Nyerguds
2
Hai Nyerguds. Untuk menjawab pertanyaan Anda, kata kunci "ini" digunakan untuk menjadikan fungsi metode ekstensi. Untuk informasi lebih lanjut tentang metode ekstensi, lihat artikel MSDN ini
JFish222
6

Lebih efisien (cepat) untuk menggunakan Buffer.BlockCopylebih 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));

Saya menulis sebuah program pengujian sederhana yang "menghangatkan Jitter", dikompilasi dalam mode rilis dan menjalankannya tanpa debugger terpasang, di mesin saya.

Untuk 10.000.000 iterasi contoh dalam pertanyaan

Concat mengambil 3088 ms

CopyTo mengambil 1079ms

BlockCopy mengambil 603ms

Jika saya mengubah array tes menjadi dua urutan dari 0 hingga 99 maka saya mendapatkan hasil yang mirip dengan ini,

Concat mengambil 45945 ms

CopyTo mengambil 2230 ms

BlockCopy mengambil 1689ms

Dari hasil ini saya dapat menyatakan bahwa metode CopyTodan BlockCopysecara signifikan lebih efisien daripada Concatdan selanjutnya, jika kinerja adalah tujuan, BlockCopymemiliki nilai lebih CopyTo.

Untuk menolak jawaban ini, jika kinerja tidak masalah, atau akan ada beberapa iterasi memilih metode yang Anda temukan paling mudah. Buffer.BlockCopymemang menawarkan beberapa utilitas untuk konversi tipe di luar cakupan pertanyaan ini.

Jodrell
sumber
6

Jawaban Terlambat :-).

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
sumber
3

Struktur yang paling efisien dalam hal RAM (dan CPU) untuk menampung array gabungan adalah kelas khusus yang mengimplementasikan IEnumerable (atau jika Anda ingin bahkan berasal dari Array) dan menghubungkan secara internal ke array asli untuk membaca nilai-nilai. AFAIK Concat melakukan hal itu.

Dalam kode sampel Anda, Anda dapat menghilangkan .ToArray (), yang akan membuatnya lebih efisien.

TToni
sumber
3

Maaf untuk menghidupkan kembali utas lama, tetapi bagaimana dengan ini:

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

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

Kemudian dalam kode Anda:

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

Sampai Anda menelepon .ToArray(),, .ToList()atau .ToDictionary(...), memori tidak dialokasikan, Anda bebas untuk "membangun permintaan Anda" dan baik memanggil salah satu dari ketiganya untuk menjalankannya atau hanya melalui semuanya dengan menggunakan foreach (var i in z){...}klausa yang mengembalikan item pada suatu waktu dari yield return t;atas...

Fungsi di atas dapat dibuat menjadi ekstensi sebagai berikut:

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

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

Jadi dalam kode, Anda dapat melakukan sesuatu seperti:

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

Sisanya sama dengan sebelumnya.

Satu perbaikan lain untuk ini akan berubah T[]menjadi IEnumerable<T>(sehingga params T[][]menjadi params IEnumerable<T>[]) untuk membuat fungsi-fungsi ini menerima lebih dari sekadar array.

Semoga ini membantu.

nurchi
sumber
2

Anda dapat melakukannya dengan cara yang telah Anda sebutkan, atau jika Anda ingin benar-benar manual tentang hal itu Anda dapat memutar loop Anda sendiri:

        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];
rambut gimbal
sumber
@nawfal Saya pikir itu akan tergantung pada ukuran array. Ini memenangkan tes ukuran array kecil saya.
amalgamate
2

Saya telah menemukan solusi satu baris yang elegan menggunakan ekspresi LINQ atau Lambda , keduanya bekerja sama (LINQ dikonversi ke Lambda ketika program dikompilasi). Solusinya bekerja untuk semua jenis array dan sejumlah array.

Menggunakan LINQ:

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

Menggunakan Lambda:

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

Saya telah menyediakan keduanya untuk preferensi seseorang. Solusi kinerja @Sergey Shteyn atau @ deepee1 sedikit lebih cepat, ekspresi Lambda menjadi yang paling lambat. Waktu yang dibutuhkan tergantung pada jenis elemen array, tetapi kecuali jika ada jutaan panggilan, tidak ada perbedaan yang signifikan antara metode.

Marko Grešak
sumber
1

Yang perlu Anda ingat adalah bahwa ketika menggunakan LINQ Anda memanfaatkan eksekusi tertunda. Metode lain yang dijelaskan di sini semuanya bekerja dengan sempurna, tetapi mereka dieksekusi segera. Lebih lanjut, fungsi Concat () mungkin dioptimalkan dengan cara yang tidak dapat Anda lakukan sendiri (panggilan ke API internal, panggilan OS, dll.). Pokoknya, kecuali jika Anda benar-benar perlu mencoba dan mengoptimalkan, Anda saat ini berada di jalur Anda ke "root of all evil";)

Siewers
sumber
1

Coba yang berikut ini:

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

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

Inilah jawaban saya:

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

Metode ini dapat digunakan pada level inisialisasi, misalnya untuk menentukan rangkaian statis array statis:

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

Namun, ada dua peringatan yang perlu Anda pertimbangkan:

  • The Concat Metode menciptakan iterator lebih baik array: tidak membuat array baru, sehingga menjadi efisien dalam hal memori yang digunakan: Namun, berikutnya  ToArray  akan meniadakan keuntungan seperti itu, karena benar-benar akan membuat array baru dan mengambil memori untuk array baru.
  • Seperti yang dikatakan @Jodrell, Concatakan agak tidak efisien untuk array besar: seharusnya hanya digunakan untuk array berukuran sedang.

Jika membidik kinerja adalah suatu keharusan, metode berikut ini dapat digunakan sebagai gantinya:

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

Atau (untuk penggemar satu liners):

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

Meskipun metode terakhir jauh lebih elegan, yang pertama jelas lebih baik untuk kinerja.

Untuk info tambahan, silakan merujuk ke posting ini di blog saya.

Darkseal
sumber
0

Bagi int [] apa yang telah Anda lakukan terlihat baik bagi saya. jawaban astander juga cocok untuknyaList<int> .

mezoid
sumber
2
Concat juga berfungsi untuk Daftar <int>. Itulah yang hebat tentang Concat, ia bekerja pada IEnumerable <>
Mike Two
0

Untuk array yang lebih kecil <10.000 elemen:

using System.Linq;

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

int[] result = firstArray.ToList().Concat(secondArray.ToList()).toArray();
Michail Michailidis
sumber
mengapa menggunakan Linq ketika Anda tidak perlu ?!
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;
    }
}

Saya pikir solusi di atas lebih umum & lebih ringan daripada yang saya lihat di sini. Ini lebih umum karena tidak membatasi penggabungan hanya untuk dua array dan lebih ringan karena tidak menggunakan LINQ atau Daftar.

Perhatikan bahwa solusinya singkat dan tambahan umum tidak menambah overhead runtime yang signifikan.

drowa
sumber
Saya akan merekomendasikan mencoba untuk menemukan pertanyaan yang lebih baru atau yang belum memiliki banyak jawaban - termasuk yang sama seperti Anda.
Andrew Barber
Saya mengusulkan solusi ini karena saya pikir ini merangkum apa yang baik dari yang lain. Itu dibuat.
drowa
-2

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

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

Milad Doraki
sumber
2
Unionbukan cara yang sangat baik untuk melakukan ini karena secara implisit memanggil Distinctdan menghapus duplikat dari koleksi yang bergabung. Concatjauh lebih baik, tetapi sudah ada di pertanyaan awal.
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
sumber