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 }));
Щас пользуюсь
int[] z = x.Concat(y).ToArray();
Есть ли более простой или эффективный метод?
Ответы:
источник
params
.System.IO.Directory.GetFiles()
возвращает массив строк.Попробуй это:
источник
List<int> list = new List<int>(x);
Вы можете написать метод расширения:
Затем:
источник
Copy
быстрее чемCopyTo
? Хотите разработать?Я остановился на более универсальном решении, которое позволяет объединять произвольный набор одномерных массивов одного типа. (Я объединял 3+ за раз.)
Моя функция:
И использование:
источник
params T[][]
чтобыthis T[][]
сделать его расширением.Это оно:
источник
int[] result = array1.ToList().Concat(array2.ToList()).toArray();
Вы не можете применять Concat непосредственно к массивамtoArray()
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
int[] result = ?
, вы скрываете проблему своего ответа заvar
тем, что ваш результат будетIEnumerable<int>
, а неint[]
. (одна из причин, почему мне не нравятсяvar
возвраты метода).ToArray()
вызова этот код не будет возвращать фактический массив, поэтому это также неверный ответ.Вы можете снять вызов ToArray () с конца. Есть ли причина, по которой вам нужен массив после вызова Concat?
Вызов Concat создает итератор для обоих массивов. Он не создает новый массив, поэтому вы не использовали больше памяти для нового массива. Когда вы вызываете ToArray, вы фактически создаете новый массив и занимает память для нового массива.
Так что, если вам просто нужно перебрать и то и другое, просто вызовите Concat.
источник
Я знаю, что OP был только немного любопытен относительно производительности. Эти большие массивы могут получить другой результат (см. @KurdishTree). И это обычно не имеет значения (@ jordan.peoples). Тем не менее, мне было любопытно, и поэтому я сошел с ума (как объяснял @TigerShark) .... Я имею в виду, что я написал простой тест на основе исходного вопроса .... и всех ответов ....
Результат был:
Ролл свои собственные победы.
источник
CopyTo
он будет самым быстрым и примерно в 3 раза быстрее, чемRoll your own
.Будьте осторожны с
Concat
методом. Сообщение конкатенации массивов в C # объясняет, что:Будет неэффективно для больших массивов. Это означает, что
Concat
метод предназначен только для массивов размера meduim (до 10000 элементов).источник
источник
Более эффективный (быстрее) , чтобы использовать
Buffer.BlockCopy
болееArray.CopyTo
,Я написал простую тестовую программу, которая «подогревает джиттер», скомпилирован в режиме релиза и запускал ее без подключенного отладчика на моей машине.
За 10 000 000 итераций примера в вопросе
Если я изменю тестовые массивы на две последовательности от 0 до 99, то я получу результаты, подобные этим,
Из этих результатов можно утверждать , что
CopyTo
иBlockCopy
методы значительно более эффективны , чемConcat
и , кроме того, если производительность является целью,BlockCopy
имеет значение , превышающееCopyTo
.Чтобы пояснить этот ответ, если производительность не имеет значения, или будет несколько итераций, выберите метод, который вы находите самым простым.
Buffer.BlockCopy
действительно предлагает некоторую полезность для преобразования типов, выходящую за рамки этого вопроса.источник
Поздний ответ :-).
источник
Наиболее эффективной структурой с точки зрения ОЗУ (и ЦП) для хранения объединенного массива будет специальный класс, который реализует IEnumerable (или, если хотите, даже наследуется от Array) и внутренне связывается с исходными массивами для чтения значений. AFAIK Concat делает именно это.
В вашем примере кода вы можете опустить .ToArray (), что сделает его более эффективным.
источник
Извините, что оживил старую ветку, но как насчет этого:
Тогда в вашем коде:
До тех пор пока вы не вызовете
.ToArray()
,.ToList()
или.ToDictionary(...)
, память не выделяется, вы можете «построить свой запрос» и либо вызов одного из этих трех , чтобы выполнить его или просто пройти их все, используяforeach (var i in z){...}
положение , которое возвращает элемент , в то время отyield return t;
выше...Вышеупомянутая функция может быть превращена в расширение следующим образом:
Таким образом, в коде вы можете сделать что-то вроде:
В остальном то же самое, что и раньше.
Еще одно улучшение к этому будет превращаться
T[]
вIEnumerable<T>
(такparams T[][]
что станетparams IEnumerable<T>[]
) , чтобы сделать эти функции принимают больше , чем просто массивы.Надеюсь это поможет.
источник
Вы можете сделать это так, как вы упомянули, или, если вы хотите получить действительно руководство по этому поводу, вы можете запустить свой собственный цикл:
источник
Я нашел элегантное однострочное решение с использованием выражения LINQ или Lambda , оба работают одинаково (LINQ преобразуется в Lambda при компиляции программы). Решение работает для любого типа массива и для любого количества массивов.
Используя LINQ:
Используя лямбду:
Я предоставил оба по своему вкусу. С точки зрения производительности решения @Sergey Shteyn или @ deepee1 немного быстрее, а лямбда-выражение - самое медленное. Требуемое время зависит от типа (ов) элементов массива, но если нет миллионов вызовов, между методами нет существенной разницы.
источник
Что вам нужно помнить, так это то, что при использовании LINQ вы используете отложенное выполнение. Все описанные здесь методы работают отлично, но они выполняются немедленно. Кроме того, функция Concat (), вероятно, оптимизирована таким образом, что вы не можете делать это самостоятельно (вызовы внутренних API, вызовы ОС и т. Д.). В любом случае, если вам действительно не нужно пытаться оптимизировать, вы находитесь на пути к «корню всего зла»;)
источник
Попробуйте следующее:
источник
Вот мой ответ:
Этот метод может использоваться на уровне инициализации, например, для определения статической конкатенации статических массивов:
Тем не менее, он имеет две оговорки, которые необходимо учитывать:
Concat
Метод создает итератор обоих массивов: он не создает новый массив, таким образом , является эффективным с точки зрения используемой памяти: однако, последующийToArray
будет отрицать такое преимущество, так как оно будет на самом деле создать новый массив и занимают память для новый массив.Concat
было бы довольно неэффективно для больших массивов: его следует использовать только для массивов среднего размера.Если стремление к производительности является обязательным, можно использовать следующий метод:
Или (для однолинейных фанатов):
Хотя последний метод намного более элегантен, первый, безусловно, лучше для производительности.
Для получения дополнительной информации, пожалуйста, обратитесь к этой записи в моем блоге.
источник
Для int [] то, что вы сделали, выглядит хорошо для меня. astander в ответ также будет работать хорошо
List<int>
.источник
Для меньших массивов <10000 элементов:
источник
Я думаю, что вышеупомянутое решение является более общим и более легким, чем другие, которые я видел здесь. Он более общий, потому что он не ограничивает конкатенацию только для двух массивов и легче, потому что он не использует ни LINQ, ни List.
Обратите внимание, что решение является кратким, и добавленная универсальность не добавляет значительных накладных расходов во время выполнения.
источник
int [] x = new int [] {1, 2, 3}; int [] y = new int [] {4, 5};
int [] z = x.Union (y) .ToArray ();
источник
Union
это не очень хороший способ сделать это, поскольку он неявно вызываетDistinct
и удаляет любые дубликаты из объединенной коллекции.Concat
намного лучше, но это уже в оригинальном вопросе.источник