Jak mogę dodać nowe elementy tablicy na początku tablicy w JavaScript?

1583

Mam potrzebę dodania lub dodania elementów na początku tablicy.

Na przykład, jeśli moja tablica wygląda jak poniżej:

[23, 45, 12, 67]

Odpowiedź z mojego wywołania AJAX brzmi 34: chcę, aby zaktualizowana tablica wyglądała następująco:

[34, 23, 45, 12, 67]

Obecnie planuję to zrobić w następujący sposób:

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

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

theArray = newArray;
delete newArray;

Czy jest na to lepszy sposób? Czy Javascript ma jakieś wbudowane funkcje, które to robią?

Złożoność mojej metody jest O(n)i byłoby naprawdę interesujące zobaczyć lepsze implementacje.

Księżyc
źródło
9
FYI: Jeśli musisz ciągle wstawiać element na początku tablicy, szybciej jest używać pushinstrukcji, po których następuje wywołanie reverse, zamiast wywoływania przez unshiftcały czas.
Jenny O'Reilly,
2
@ JennyO'Reilly powinieneś opublikować to jako odpowiedź. Idealnie pasowało do mojego przypadku użycia. dzięki
rob
2
Testy wydajności: jsperf.com/adding-element-to-the-array-start Ale wyniki są różne dla każdej przeglądarki.
Avernikoz

Odpowiedzi:

2810

Zastosowanie unshift. To jest tak push, że dodaje elementy na początku tablicy zamiast na końcu.

  • unshift/ push- dodaj element na początku / końcu tablicy
  • shift/ pop - usuń i zwróć pierwszy / ostatni element tablicy

Prosty schemat ...

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

i wykres:

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

Sprawdź dokumentację macierzy MDN . Praktycznie każdy język, który ma możliwość wypychania / wyskakiwania elementów z tablicy, będzie miał również możliwość cofania / zmiany (czasem nazywanych push_front/ pop_front) elementów, nigdy nie powinieneś ich implementować.


Jak wskazano w komentarzach, jeśli chcesz uniknąć mutowania oryginalnej tablicy, możesz użyć concat, która łączy dwie lub więcej tablic razem. Możesz użyć tego, aby funkcjonalnie popchnąć pojedynczy element na przód lub tył istniejącej tablicy; aby to zrobić, musisz przekształcić nowy element w tablicę z jednym elementem:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

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

concatmoże również dodawać elementy. Argumenty concatmogą być dowolnego typu; są domyślnie opakowane w tablicę jednoelementową, jeśli nie są już tablicą:

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 ]
Meagar
źródło
51
concatKorzystne może być użycie, ponieważ zwraca nową tablicę. Bardzo przydatny do tworzenia łańcuchów. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)itp ... Jeśli użyjesz unshift, nie możesz wykonać tego łańcucha, ponieważ wszystko, co otrzymasz, to długość.
StJohn3D
4
shift / unshift, push / pop, splice. Bardzo logiczne nazwy dla takich metod.
linuxunil
1396

obraz operacji tablicowych

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

Maksym
źródło
117
Powodem, dla którego ludzie potrzebują wizualnych wskazówek dla 4 codziennych funkcji, są zaszyfrowane nazwy funkcji ... Dlaczego unshift nie jest nazywany Insert? Shift powinien być Usuń. itp ...
Pascal
76
// Dlaczego unshift nie jest nazywany Insert? // Pochodzi z konwencji języka programowania C, w których elementy tablicy traktowano jak stos. (patrz perlmonks.org/?node_id=613129 dla pełnego wyjaśnienia)
dreftymac
25
@Pascal Nie, wstawianie i usuwanie byłoby w tym przypadku szczególnie złymi nazwami; implikują losowy dostęp, zamiast dodawania / usuwania z przodu tablicy
meagar
25
Myślałem, że cofnięcie powinno usunąć pierwszy klucz, a shift wstawi przy pierwszym kluczu, ale to tylko moja ogólna myśl
Shannon Hochkins,
27
Podoba mi się odniesienie do DNA
Hunter WebDev,
235

W przypadku ES6 użyj operatora rozkładania ...:

PRÓBNY

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

console.log(arr)

Abdennour TOUMI
źródło
19
tworzy także nową tablicę, przydatną do czystych funkcji
devonj
jaki jest tutaj wpływ na wydajność? Czy jest wolniejszy niż użycie unshift ()?
Peter T.
1
Jasne, będzie wolniej, ponieważ jest to niezmienna tablica (tworzenie nowej tablicy). Jeśli pracujesz z dużą tablicą lub wydajność jest Twoim pierwszym wymaganiem, rozważ użycie concatzamiast tego.
Abdennour TOUMI
wydajność nie jest ważna w 2018 r., nowe wersje w przeglądarce i węźle mają taką samą wydajność
stackdave
75

Kolejny sposób to zrobić concat

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

Różnica między concati unshiftpolega na tym, że concatzwraca nową tablicę. Występ między nimi można znaleźć tutaj .

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

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

Oto wynik testu

wprowadź opis zdjęcia tutaj

zangw
źródło
Dobrze byłoby, gdyby Twoja odpowiedź zawierała porównanie wydajności obu oprócz dodania odwołania.
Ivan De Paz Centeno
Właśnie dostałem, że jsPerf jest tymczasowo niedostępny, gdy pracujemy nad wydaniem v2. Spróbuj ponownie później z linku. Kolejny dobry powód, aby dołączyć wyniki zamiast linkowania do nich.
Tigger,
wynik jsPrefunshift : 25 2510 ± 3,18% 99% wolniej concat: 2436894 ± 3,39% najszybciej
iluminator
W najnowszym Safari fn_unshift () działa szybciej.
passatgt
W najnowszym Safari (v 10) funkcja fn_unshift () znów działa wolniej.
rmcsharry
45

Szybki ściąg:

Terminy shift / unshift i push / pop mogą być nieco mylące, przynajmniej dla osób, które mogą nie znać programowania w C.

Jeśli nie znasz języka lingo, oto szybkie tłumaczenie alternatywnych terminów, które mogą być łatwiejsze do zapamiętania:

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

* array_push()     -  (aka Append ;; InsertAfter   ;; InsertAtEnd )     
* array_pop()      -  (aka UnAppend ;; RemoveAfter   ;; RemoveFromEnd ) 
dreftymac
źródło
20

masz tablicę: var arr = [23, 45, 12, 67];

Aby dodać element na początku, chcesz użyć splice:

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

ozimax06
źródło
arr. plama (0, arr. długość, 34);
Lior Elrom,
1
@LiorElrom, co robi Twój fragment?
Janus Troelsen
@poushy jest specyficzny dla przeglądarki, w Firefox 54 jest o unshift50% szybszy (ale w większości bardziej czytelny)
icl7126
@poushy Już nie. O wiele wolniej.
Andrew
17

Bez mutacji

Właściwie wszystko unshift / pushi shift/ pop mutują tablicę początkową.

unshift/ pushDodać element do istniejącej tablicy od rozpoczęcia / zakończenia i shift/ popusunąć element z początku / końca tablicy.

Ale istnieje kilka sposobów dodawania elementów do tablicy bez mutacji. wynikiem jest nowa tablica, aby dodać na końcu tablicy użyj poniższego kodu:

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

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

Aby dodać na początek oryginalnej tablicy, użyj poniższego kodu:

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

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

W powyższy sposób dodajesz na początku / na końcu tablicy bez mutacji.

AmerllicA
źródło
Po prostu umieściłem slicefunkcję na końcu, originArrayaby zapobiec jej zmienności.
Ahmad Khani,
1
Niesamowite! Jeśli chodzi o zarządzanie stanem (Redux) ... ta odpowiedź jest cenna!
Pedro Ferreira
1
To jest właściwy sposób!
mmm
10

Korzystanie z destrukcji ES6: (unikanie mutacji oryginalnej tablicy)

const newArr = [item, ...oldArr]

Ben Adam
źródło
9

var testdata = new Array();
testdata = [23, 45, 12, 67];
testdata = [34, ...testdata]; 
console.log(testdata)

Tirkesh Turkesh
źródło
1
To jest ta sama odpowiedź, co Abdennour TOUMI
T04435
8

Jeśli musisz ciągle wstawiać element na początku tablicy, szybciej jest używać pushinstrukcji, a następnie wywoływać reverse, zamiast wywoływaćunshift cały czas.

Test porównawczy: http://jsben.ch/kLIYf

Jenny O'Reilly
źródło
1
Uwaga: tablica początkowa powinna być pusta.
192kb
5

Za pomocą splicewstawiamy element do tablicy na początku:

arrName.splice( 0, 0, 'newName1' );
Srikrushna
źródło
To poprawna odpowiedź. Dziękuję Srikrushna
Khanh Tran