Як я можу додати нові елементи масиву на початку масиву в Javascript?


1584

У мене є необхідність додавати або додавати елементи на початку масиву.

Наприклад, якщо мій масив виглядає нижче:

[23, 45, 12, 67]

І відповідь на мій дзвінок AJAX 34: я хочу, щоб оновлений масив був таким:

[34, 23, 45, 12, 67]

В даний час я планую це зробити так:

var newArray = [];
newArray.push(response);

for (var i = 0; i < theArray.length; i++) {
    newArray.push(theArray[i]);
}

theArray = newArray;
delete newArray;

Чи є кращий спосіб зробити це? Чи у Javascript є якась вбудована функціональність, яка це робить?

Складність мого методу полягає в тому, O(n)що було б цікаво побачити кращі втілення в життя.


9
FYI: Якщо вам потрібно постійно вставляти елемент на початку масиву, швидше використовувати pushоператори з подальшим викликом reverse, а не виклик unshiftвесь час.
Дженні О'Рейлі

2
@ JennyO'Reilly, ви повинні опублікувати це як відповідь. Чудово відповідав моєму випадку використання. дякую
пограбуйте

2
Тести на ефективність: jsperf.com/adding-element-to-the-array-start Але результати різні для кожного браузера.
Авернікоз

Відповіді:


2810

Використовуйте unshift. Це як push, за винятком того, що додає елементи на початок масиву замість кінця.

  • unshift/ push- додати елемент до початку / кінця масиву
  • shift/ pop - видалити та повернути перший / останній елемент масиву

Проста схема ...

   unshift -> array <- push
   shift   <- array -> pop

та діаграма:

          add  remove  start  end
   push    X                   X
    pop           X            X
unshift    X             X
  shift           X      X

Ознайомтеся з документацією на масив MDN . Практично кожна мова, яка має здатність натискати / виконувати елементи з масиву, також матиме можливість змінити / зміщувати (іноді називаються push_front/ pop_front) елементи, вам ніколи не доведеться їх реалізовувати самостійно.


Як зазначено в коментарях, якщо ви хочете уникнути мутації свого початкового масиву, ви можете використовувати concat, який об'єднує два або більше масивів разом. Ви можете використовувати це для функціонального натискання одного елемента на передню або задню частину наявного масиву; для цього вам потрібно перетворити новий елемент в єдиний масив елементів:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]

concatтакож можна додавати елементи. Аргументи до concatможуть бути будь-якого типу; вони неявно загорнуті в одноелементний масив, якщо вони вже не є масивом:

const array = [ 3, 2, 1 ]

const newLastElement  = 0

// Both of these lines are equivalent:
const newArray1 = array.concat(newLastElement)   // [ 3, 2, 1, 0 ]
const newArray2 = array.concat([newLastElement]) // [ 3, 2, 1, 0 ]

51
Використання concatможе бути кращим, оскільки воно повертає новий масив. Дуже корисно для прикування. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)і т.д. ... Якщо ви використовуєте unshift, ви не можете робити це прикування, тому що все, що ви отримаєте назад, - це довжина.
StJohn3D

4
зсув / зсув, натискання / попс, сплайс. Дуже логічні назви таких методів.
linuxunil

1396

зображення масиву операцій

var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]


117
Причина, чому людям потрібна наочна настанова для 4-х щоденних функцій, що використовуються, це через зашифровані назви функцій ... Чому невмилий не називається Вставити? Зсув має бути видалений. тощо ...
Паскаль

76
// Чому невмилий не називається Insert? // Походить із умовних положень мови програмування C, де елементи масиву обробляються як стек. (дивіться perlmonks.org/?node_id=613129 для повного пояснення)
dreftymac

25
@Pascal Ні, вставка та видалення були б для цього особливо поганими іменами; вони мають на увазі випадковий доступ, замість того, щоб додавати / видаляти з передньої частини масиву
meagar

25
Я міг би подумати, що при швидкому зсуві слід видалити перший ключ, а зміна вставити при першому ключі, але це лише моя загальна думка
Шеннон Хочкінс,

27
Мені подобається посилання на ДНК
Hunter WebDev

235

За допомогою ES6 використовуйте оператор розкидання ...:

DEMO

var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34,23, 45, 12, 67]

console.log(arr)


19
також створює новий масив, корисний для чистих функцій
devonj

що тут має значення для продуктивності? Це повільніше, ніж використання unshift ()?
Пітер Т.

1
Звичайно, це буде повільніше, оскільки це незмінний масив (створення нового масиву). Якщо ви працюєте з великим масивом або продуктивність є вашою першою вимогою, будь ласка, подумайте про використання concat.
Abdennour TOUMI

продуктивність не важлива в 2018 році, нові версії браузера та вузла отримують однакову продуктивність
stackdave

75

Ще один спосіб зробити це через concat

var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));

Різниця між concatі unshiftполягає в тому, що concatповертає новий масив. Виступ між ними можна знайти тут .

function fn_unshift() {
  arr.unshift(0);
  return arr;
}

function fn_concat_init() {
  return [0].concat(arr)
}

Ось результат тесту

введіть тут опис зображення


До Вашої відповіді було б додати порівняння ефективності обох, крім додавання посилання.
Іван Де Пас Сентено

Щойно я отримав jsPerf тимчасово недоступний, поки ми працюємо над випуском v2. Повторіть спробу пізніше за посиланням. Ще одна вагома причина включити результати замість посилань на них.
Тигр

Результат jsPrefunshift :: 25,510 ± 3,18% 99% повільніше concat: 2436,894 ± 3,39% найшвидший
Illuminator

В останньому Safari fn_unshift () працює швидше.
passatgt

В останньому Safari (v 10) fn_unshift () знову повільніше.
rmcsharry

45

Швидка шпаргалка:

Терміни shift / unhift і push / pop можуть бути дещо заплутаними, принаймні для людей, які, можливо, не знайомі з програмуванням в C.

Якщо ви не знайомі з лінгвом, ось короткий переклад альтернативних термінів, який може бути простіше запам’ятати:

* array_unshift()  -  (aka Prepend ;; InsertBefore ;; InsertAtBegin )     
* array_shift()    -  (aka UnPrepend ;; RemoveBefore  ;; RemoveFromBegin )

* array_push()     -  (aka Append ;; InsertAfter   ;; InsertAtEnd )     
* array_pop()      -  (aka UnAppend ;; RemoveAfter   ;; RemoveFromEnd ) 

20

у вас є масив: var arr = [23, 45, 12, 67];

Щоб додати елемент до початку, потрібно використовувати splice:

var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);


arr.splice (0, arr.length, 34);
Ліор Елром

1
@LiorElrom, що робить ваш фрагмент?
Янус Троельсен

@poushy - це специфічний для браузера, у Firefox 54 на unshift50% швидше (але в основному читабельніше)
icl7126

@poushy Більше. Шлях повільніше.
Андрій

17

Без мутації

Насправді всі unshift/ pushта shift/ pop мутують вихідний масив.

unshift/ pushДодати елемент до існуючого масиву з початку / кінця і shift/ popвидалити елемент з початку / кінця масиву.

Але є кілька способів додати елементи до масиву без мутації. результат - новий масив, який потрібно додати до кінця використання масиву нижче коду:

const originArray = ['one', 'two', 'three'];
const newItem = 4;

const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+

Щоб додати до початку вихідного масиву, використовуйте нижче код:

const originArray = ['one', 'two', 'three'];
const newItem = 0;

const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+

Вищенаведеним способом ви додаєте до початку / кінця масиву без мутації.


Я просто поставив sliceфункцію в кінці, originArrayщоб запобігти її зміни.
Ахмад Хані

1
Дивовижно! Коли йдеться про (Redux) державне управління ... ця відповідь дорогоцінна!
Педро Феррейра

1
Це правильний шлях!
ммм

10

Використання ES6 деструктуризації: (уникнення мутації від вихідного масиву)

const newArr = [item, ...oldArr]



8

Якщо вам потрібно постійно вставляти елемент на початку масиву, швидше використовувати pushоператори, за якими слід виклик reverse, а не постійно дзвонити unshift.

Тест тестування: http://jsben.ch/kLIYf


1
Примітка: початковий масив повинен бути порожнім.
192кб

5

Використовуючи spliceми вставляємо елемент до масиву на початку:

arrName.splice( 0, 0, 'newName1' );

Це правильна відповідь. Дякую Шрікрушна
Хан Тран
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.