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.