Merging two arrays in .NET
Is there a built in function in .NET 2.0 that will take two arrays and merge them into one array?
The arrays are both of the same type. I’m getting these arrays from a widely used function within my code base and can’t modify the function to return the data in a different format.
I’m looking to avoid writing my own function to accomplish this if possible.
26 Answers 26
In C# 3.0 you can use LINQ’s Concat method to accomplish this easily:
In C# 2.0 you don’t have such a direct way, but Array.Copy is probably the best solution:
This could easily be used to implement your own version of Concat .
Keep in mind, this will remove duplicates. If you want to keep duplicates, use Concat.
![]()
If you can manipulate one of the arrays, you can resize it before performing the copy:
Otherwise, you can make a new array
If you don’t want to remove duplicates, then try this
![]()
First, make sure you ask yourself the question «Should I really be using an Array here»?
Unless you’re building something where speed is of the utmost importance, a typed List, like List<int> is probably the way to go. The only time I ever use arrays are for byte arrays when sending stuff over the network. Other than that, I never touch them.
Easier would just be using LINQ:
First convert the arrays to lists and merge them. After that just convert the list back to an array 🙂
![]()
I think you can use Array.Copy for this. It takes a source index and destination index so you should be able to append the one array to the other. If you need to go more complex than just appending one to the other, this may not be the right tool for you.
Everyone has already had their say but I think this more readable than the «use as Extension method» approach:
However it can only be used when bringing together 2 arrays.
This is what I came up with. Works for a variable number of arrays.
Assuming the destination array has enough space, Array.Copy() will work. You might also try using a List<T> and its .AddRange() method.
Personally, I prefer my own Language Extensions, which I add or remove at will for rapid prototyping.
Following is an example for strings.
It is much faster than LINQ and Concat. Faster still, is using a custom IEnumerable Type-wrapper which stores references/pointers of passed arrays and allows looping over the entire collection as if it were a normal array. (Useful in HPC, Graphics Processing, Graphics render. )
Your Code:
For the entire code and a generics version see: https://gist.github.com/lsauer/7919764
Note: This returns an unextended IEnumerable object. To return an extended object is a bit slower.
I compiled such extensions since 2002, with a lot of credits going to helpful people on CodeProject and ‘Stackoverflow’. I will release these shortly and put the link up here.
![]()
Just to have it noted as an option: if the arrays you are working with are of a primitive type – Boolean (bool), Char, SByte, Byte, Int16 (short), UInt16, Int32 (int), UInt32, Int64 (long), UInt64, IntPtr, UIntPtr, Single, or Double – then you could (or should?) try using Buffer.BlockCopy. According to the MSDN page for the Buffer class:
This class provides better performance for manipulating primitive types than similar methods in the System.Array class.
Using the C# 2.0 example from @OwenP’s answer as a starting point, it would work as follows:
There is barely any difference in syntax between Buffer.BlockCopy and the Array.Copy that @OwenP used, but this should be faster (even if only slightly).
![]()
I needed a solution to combine an unknown number of arrays.
Surprised nobody else provided a solution using SelectMany with params .
If you don’t want distinct items just remove distinct.
Note: There is definitely no guarantee of ordering when using distinct.
In case someone else is looking for how to merge two image byte arrays:
If you have the source arrays in an array itself you can use SelectMany:
Probably this is not the fastest method but might fit depending on usecase.
Here is a simple example using Array.CopyTo. I think that it answers your question and gives an example of CopyTo usage — I am always puzzled when I need to use this function because the help is a bit unclear — the index is the position in the destination array where inserting occurs.
I guess you can’t get it much simpler.
![]()
I’m assuming you’re using your own array types as opposed to the built-in .NET arrays:
Another way of doing this would be using the built in ArrayList class.
Both examples are C#.
![]()
Using the above code two Arrays can be easily merged.
Created and extension method to handle null
![]()
![]()
I wanted to find an approach without using any libraries or functionality beyond arrays themselves.
The first two examples are mostly for reading the logic from scratch, but I also wonder if there could be performance variations depending on the sitaution.
The third example is the most practical choice.
Lastly, I made a fourth example, that can merge multiple arrays, using the params keyword.
The way it works when using params, is that the single-dimension arrays are passed into a jagged array.
GetLength(0) returns the number of arrays contained within the jagged array.
The code first counts the Length of all the arrays, then it initializes a new array based on that size, and starts adding entire arrays into the new results array by using the CopyTo() method, while adding the Length of each added array to an index counter.
PS: Some times it is necessary to remove empty items, or certain items, from arrays when merging.
This function can be combined with the ones above.
It takes an array, counts the number of items that match zero. And creates a new array of the proper size. Then the counter is recycled and used as an index, for where to put place the input array’s values into the new and smaller result array. When an item matches zero, it skips the rest of the code in that round of the loop, and continues with the next round, without incrementing the integer counter.
Как объединить массивы в C++?

Программирование и разработка
Предположим, что у вас есть массив из 5 символов и другой массив из 8 символов. Если эти два массива объединены в один, то оба массива были объединены. В новом массиве будет 13 символов (= 5 + 8). Порядок, в котором различные элементы массива расположены в новом массиве, не имеет значения; и это слияние двух массивов.
В C ++ существует техническая проблема в том смысле, что в результате получается три массива вместо одного нового объединенного массива. Было бы неплохо после слияния удалить два старых массива и освободить неиспользуемую память? В C ++ есть два способа объединения двух массивов: если два массива объединились, использовалась динамическая память, то их можно удалить, чтобы в итоге получился один массив; в противном случае программист получает три массива.
Слияние массивов путем простого размещения одного массива позади другого — это хорошо; но может быть лучше иметь минимальную сортировку по мере объединения массивов. Сортировка в целом — это целая тема в программировании. Сортировка в целом в этой статье не рассматривается. Однако рассматривается очень простая минимальная сортировка.
В этой статье объясняется, как объединить два массива, чтобы получить три массива, и как объединить два массива, чтобы получить один массив. Также рассматривается некоторая минимальная сортировка. Чтобы объединить два массива, они должны быть одного типа.
Процедура объединения двух массивов может быть расширена до более чем двух массивов.
Слияние массивов без бесплатного хранилища
Слияние без сортировки
Рассмотрим следующие два массива:
В первом 5 элементов, а во втором 8 элементов. Если элементы второго массива каким-либо образом подогнать к задней части первого массива, будет сформирован массив из 13 элементов. Чтобы достичь этого без использования свободного хранилища (динамической памяти), сначала необходимо создать третий массив из 13 пустых значений. Затем 5 значений первого массива будут скопированы в первые 5 местоположений третьего массива. Затем 8 значений второго массива будут скопированы в оставшиеся 8 позиций третьего массива. Третий массив становится объединенным и желаемым массивом. Следующая программа иллюстрирует это:
Обратите внимание на то, как индексация использовалась в циклах for. Проблема этой схемы в том, что первые два массива стали избыточными. Теперь они без надобности занимают память компьютера. Без свободного хранилища (динамической памяти) массивы не могут быть удалены из памяти, пока они не выйдут за пределы области видимости. Чтобы решить эту проблему, воспользуйтесь бесплатным магазином — см. Ниже.
Первый сегмент кода включает библиотеку iostream и объявляет об использовании стандартного пространства имен для остальной части программы. Остальная часть программы находится в функции main (). Первые три оператора в функции main () объявляют первый, второй и третий массивы. Следующий сегмент кода — это цикл for, который копирует все элементы из меньшего массива в третий массив. Первым можно было скопировать больший массив из первых двух; не важно.
Следующий сегмент кода использует цикл for для копирования большего массива в заднюю часть меньшего массива, уже находящегося в третьем массиве. Третий массив — это объединенный массив. Сумма количества элементов в первых двух массивах должна равняться количеству элементов в третьем массиве. Последний сегмент кода отображает значения третьего массива.
Слияние с некоторой сортировкой
При вставке элементов в третий массив вначале можно сравнивать первые элементы обоих массивов, а меньшее значение вставлять первым перед первым значением другого массива. Затем можно сравнить вторые элементы обоих массивов, и меньшее значение, вставленное в третий массив, перед вторым значением другого массива будет вставлено. Затем можно сравнить третьи элементы обоих массивов, а меньшее значение вставить перед третьим значением другого массива. Эта процедура продолжается до тех пор, пока все элементы более короткого массива не будут вставлены вместе с одинаковым количеством элементов более длинного массива. Остальные элементы более длинного массива можно просто вставить в третий массив в их порядке. Следующая программа иллюстрирует это:
Как сложить два массива вместе в С++?
Мне нужно добавить два массива вместе. Почему работает следующее?
5 ответов
Во-первых, ваш цикл for неверен. Должно быть i < 3 , а не <= .
Во-вторых, вы не инициализировали nums[] .
В-третьих, ваш цикл for ссылается на несуществующий numbs[] .
В-четвертых, i никогда не объявляется.
В-пятых, вы печатаете результат до того, как завершите его вычисление.
В-шестых, на самом деле вы не вычисляете сумму.
У меня такое чувство, что это ближе к тому, чего вы пытаетесь достичь:
Если вы пытаетесь сложить значения двух элементов массива и сохранить их в массиве, синтаксис будет таким же простым, как:
Но это предполагает, что массивы объявлены и arr2 и arr3 инициализированы.
При работе с C++ в первый раз мой совет: забудьте обо всем, что связано с C и имеет аналог C++. В этом случае прекратите использование массивов в стиле C и используйте std::array вместо этого (то же самое можно сделать с помощью std::vector , но я оставлю это в качестве упражнения читателю).
Хорошо, вы хотите изучить C++? Вот как ваша проблема вычисления суммы всех элементов массивов может быть решена в 3 строках кода с использованием С++:
Объяснение очень простое: в первой строке мы выделяем массив из 3 элементов типа int и инициализируем его тремя значениями 1, 2, 3 . Конечно, вы можете изменить эти значения на что-то другое или инициализировать их следующим образом:
Здесь важно понять, что std::array действует точно так же, как массивы в стиле C, но они более мощные и гибкие в использовании.
Во второй строке мы используем std::accumulate , стандартный алгоритм, расположенный в <algorithm> (кто бы мог подумать) для вычисления суммы всех элементов контейнера (в нашем случае nums ). Алгоритм довольно прост, и вы можете представить его как эквивалент:
Для вашего конкретного случая. Единственная большая разница в том, что вместо этого используются итераторы. Что такое итераторы? Что ж, это то, что вам придется исследовать самостоятельно. Я могу гарантировать вам, что в Интернете есть множество статей и постов, объясняющих это. Я предлагаю вам начать, например, здесь.
Просто помните, что std::begin возвращает итератор к первому элементу массива, и std::end вычислит итератор для за конечным элементом массива. Использование этих функций довольно распространено в стандартных алгоритмах, и вы должны привыкнуть к этому. Общие идеи о
Вычислите сумму всех элементов контейнера, начиная с std::begin(nums) и заканчивая (исключая) std::end(nums) , учитывая начальное значение 0 .
Как видите, сигнатура функции и параметры довольно просты. И, наконец, в последней строке мы выводим наш результат (так же, как мы делали это раньше).
Как объединить два массива в C#?
вы можете написать метод расширения:
затем:
Я остановился на более универсальном решении, которое позволяет объединять произвольный набор одномерных массивов одного и того же типа. (Я объединял 3+ одновременно.)
функции:
и использование:
вы можете взять ToArray() call off the end. Есть ли причина, по которой вам нужно, чтобы это был массив после вызова Concat?
вызов Concat создает итератор над обоими массивами. Он не создает новый массив, поэтому вы не использовали больше памяти для нового массива. Когда вы вызываете ToArray, вы фактически создаете новый массив и занимаете память для нового массива.
Так что если вам просто нужно легко перебирать оба, то просто вызовите Concat.
Я знаю, что ОП был только слегка любопытно о производительности. Что большие массивы могут получить другой результат (см. @kurdishTree). И что это обычно не имеет значения (@Иордании.народный.) Тем не менее, мне было любопытно, и поэтому я потерял рассудок ( как объяснял @TigerShark). Я имею в виду, что я написал простой тест, основанный на исходном вопросе. и все ответы.
результат:
ролл свои собственные победы.
будьте осторожны с Concat метод. Пост объединение массивов в C# поясняет, что:
будет неэффективно для больших массивов. Это означает Concat метод предназначен только для массивов размера meduim (до 10000 элементов).
более эффективно (быстрее) использовать Buffer.BlockCopy over Array.CopyTo ,
Я написал простую тестовую программу ,которая «разогревает дрожание», скомпилированную в режиме выпуска и запустила ее без отладчика, подключенного к моей машине.
для 10,000,000 итераций примера в вопросе
функция concat взял 3088ms
копировать, чтобы взял 1079ms
BlockCopy взял 603ms
если я изменяю тестовые массивы на две последовательности от 0 до 99, то я получаю результаты, подобные этому,
функция concat взял 45945ms
копировать, чтобы взял 2230ms
BlockCopy взял 1689ms
из этих результатов я могу утверждать, что CopyTo и BlockCopy методы значительно более эффективны, чем Concat и кроме того, если производительность является целью, BlockCopy имеет значение CopyTo .
чтобы предупредить этот ответ, если производительность не имеет значения, или будет несколько итераций, выберите метод, который вы найдете проще всего. Buffer.BlockCopy предлагает некоторую утилиту для преобразования типов за пределами этого вопроса.
вы можете сделать это, как вы упомянули, или если вы хотите получить действительно инструкцию об этом вы можете свернуть свой собственный цикл:
наиболее эффективной структурой с точки зрения ОЗУ (и ЦП) для хранения объединенного массива будет специальный класс, который реализует IEnumerable (или, если вы хотите, даже происходит от массива) и внутренне связывается с исходными массивами для чтения значений. Насколько мне известно, функция concat делает именно это.
в вашем примере кода Вы можете опустить .ToArray () хотя, что сделало бы его более эффективным.
вам нужно помнить, что при использовании LINQ вы используете отложенное выполнение. Другие методы, описанные здесь, все работают отлично, но они выполняются немедленно. Кроме того, функция Concat (), вероятно, оптимизирована таким образом, что вы не можете сделать это самостоятельно (вызовы внутренних API, вызовы ОС и т. д.). В любом случае, если вам действительно не нужно пытаться оптимизировать, вы в настоящее время находитесь на своем пути к «корню всего зла» 😉
Я нашел элегантное решение одной линии с помощью LINQ или лямда — выражение, оба работают одинаково (LINQ преобразуется в лямбда при компиляции программы). Решение работает для любого типа массива и для любого количества массивов.
С помощью LINQ:
С Помощью Лямбда:
Я предоставил оба для своих предпочтений. Производительность мудрый @Сергей Штейн или @deepee1 это!—4—> решения немного быстрее, лямбда-выражение является самым медленным. Затраченное время зависит от типа(ов) элементов массива, но если нет миллионов вызовов, нет существенной разницы между методами.
извините, чтобы возродить старую нить, но как насчет этого:
тогда в вашем коде:
пока ты не позвонишь .ToArray() , .ToList() или .ToDictionary(. ) , память не выделена, вы можете «построить свой запрос» и либо вызвать один из этих трех, чтобы выполнить его, либо просто пройти через них все с помощью foreach (var i in z) <. >предложение, которое возвращает элемент одновременно из yield return t; выше.
вышеуказанную функцию можно сделать в расширение как следует:
так в коде, вы можете сделать что-то вроде:
остальное то же самое, что и раньше.
еще одно улучшение к этому будет меняться T[] на IEnumerable<T> (т. е. params T[][] станет params IEnumerable<T>[] ), чтобы эти функции принимали больше, чем просто массивы.
надеюсь, что это помогает.
для int[] то, что вы сделали, выглядит хорошо для меня. astander это ответ также будет хорошо работать для List<int> .
