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.


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 ]

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]


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)


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


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 ) 

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);


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.


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]



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


1
Uwaga: tablica początkowa powinna być pusta.
192kb

5

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

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

To poprawna odpowiedź. Dziękuję Srikrushna
Khanh Tran
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.