Предполагая, что у меня есть массив, размер которого N
(где N > 0
), есть ли более эффективный способ присоединения к массиву, который не требует O (N + 1) шагов?
В коде, по сути, то, что я сейчас делаю, это
function prependArray(value, oldArray) {
var newArray = new Array(value);
for(var i = 0; i < oldArray.length; ++i) {
newArray.push(oldArray[i]);
}
return newArray;
}
javascript
arrays
prepend
samccone
источник
источник
Ответы:
Я не уверен насчет более эффективного с точки зрения big-O, но, конечно, использование
unshift
метода более лаконично:[Редактировать]
Этот бенчмарк jsPerf показывает, что он
unshift
работает прилично быстрее, по крайней мере, в нескольких браузерах, независимо от возможной разной производительности big-O, если вы согласны с изменением массива на месте. Если вы действительно не можете изменить исходный массив, сделайте что-то вроде приведенного ниже фрагмента, который, похоже, не будет значительно быстрее, чем ваше решение:[Редактировать 2]
Для полноты можно использовать следующую функцию вместо примера OP,
prependArray(...)
чтобы воспользоваться преимуществомunshift(...)
метода Array :источник
prepend
"unshift
"?unshift
звучит более подходящим для такой операции с массивом (он перемещает элементы ... более или менее физически).prepend
было бы более подходящим для связанных списков, где вы буквально добавляете элементы.push
иunshift
оба содержатu
, тогда какpop
иshift
не имеют.С ES6 вы можете теперь использовать оператор распространения, чтобы создать новый массив с вашими новыми элементами, вставленными перед исходными элементами.
Обновление 2018-08-17: Производительность
Я намеревался этот ответ представить альтернативный синтаксис, который я считаю более запоминающимся и лаконичным. Следует отметить, что согласно некоторым тестам (см. Этот другой ответ ) этот синтаксис значительно медленнее. Это, вероятно, не будет иметь значения, если вы не выполняете многие из этих операций в цикле.
источник
unshift
Если вы добавляете массив в начало другого массива, его более эффективно использовать
concat
. Так:Но это все равно будет O (N) в размере oldArray. Тем не менее, это более эффективно, чем ручная итерация по oldArray. Кроме того, в зависимости от деталей, это может помочь вам, потому что, если вы собираетесь добавить много значений, лучше сначала поместить их в массив, а затем в конце объединить oldArray, а не добавлять каждое из них по отдельности.
Нет никакого способа сделать лучше, чем O (N) в размере oldArray, потому что массивы хранятся в непрерывной памяти с первым элементом в фиксированной позиции. Если вы хотите вставить перед первым элементом, вам нужно переместить все остальные элементы. Если вам нужно обойти это, сделайте то, что сказал @GWW, и используйте связанный список или другую структуру данных.
источник
unshift
. Но обратите внимание, что a) он мутирует oldArray, аconcat
не (так, какой из них лучше для вас зависит от ситуации), и b) он вставляет только один элемент.[0]
), тогда как unshift изменяет его на месте. Но оба должны быть O (N). Также приветствует ссылку на этот сайт - выглядит очень удобно.Если вы хотите добавить массив (a1 к массиву a2), вы можете использовать следующее:
источник
f вам нужно сохранить старый массив, нарезать старый и отменить новое (ые) значение (я) в начале слайса.
источник
У меня есть несколько свежих тестов различных методов приготовления. Для небольших массивов (<1000 элементов) лидером является цикл, связанный с методом push. Для огромных массивов метод Unshift становится лидером.
Но эта ситуация актуальна только для браузера Chrome. В Firefox unshift имеет потрясающую оптимизацию и работает быстрее во всех случаях.
ES6 распространяется в 100+ раз медленнее во всех браузерах.
https://jsbench.me/cgjfc79bgx/1
источник
Есть специальный метод:
Но если вы хотите добавить несколько элементов в массив, будет быстрее использовать такой метод:
источник
Array.prototype.unshift.apply(a,b);
Пример добавления на месте:
источник
Вызов
unshift
только возвращает длину нового массива. Итак, чтобы добавить элемент в начале и вернуть новый массив, я сделал это:или просто с оператором распространения:
Таким образом, исходный массив остается нетронутым.
источник