wypychaj wiele elementów do tablicy

284

Próbuję wypchnąć wiele elementów jako jedną tablicę, ale pojawia się błąd

> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined

Próbuję robić podobne rzeczy, które zrobiłbym w rubinie, myślałem, że applyto coś w stylu *.

>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]
evfwcqcg
źródło

Odpowiedzi:

240

Podczas korzystania z większości funkcji obiektów z applylub callThe contextparametr musi być przedmiotem pracujesz dalej.

W takim przypadku potrzebujesz a.push.apply(a, [1,2])(lub bardziej poprawnie Array.prototype.push.apply(a, [1,2]))

Niet the Dark Absol
źródło
618

Możesz wcisnąć wiele elementów do tablicy w następujący sposób

var a = [];
    
a.push(1, 2, 3);

console.log(a);

amit1310
źródło
1
Ta odpowiedź i wybrana odpowiedź dają różne i być może nieoczekiwane rezultaty. a.push (1) vs. a.push ([1])
oevna
1
Czy ktoś może wyjaśnić, dlaczego ma o tyle więcej głosów niż zaakceptowana odpowiedź? Może to być łatwiejsze, ale jest mniej elastyczne. Jeśli chcesz scalić 2 tablice, to nie zadziała.
BluE
@BluE, jeśli chcesz scalić dwie tablice, po prostu użyj array.concat ()
Florent Arlandis
@FlorentArlandis array.concat nie działa, aby dodać drugą tablicę do pierwszej. Stworzy nowy. Wiem, że jest podobnie. Operator spreadu był tym, czego szukałem. Spójrz na pozostałe odpowiedzi i komentarze, aby uzyskać szczegółowe informacje.
BluE
435

Teraz w ECMAScript2015 (alias ES6) możesz użyć operatora rozkładania, aby dodać wiele elementów jednocześnie:

var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);

Zobacz tabelę zgodności Kangax ES6, aby zobaczyć, które przeglądarki są kompatybilne

canac
źródło
41
whaaaaaaat jest to niesamowite, a ponadto, jeśli zrobisz to w maszynie do pisania, skompiluje się do push.apply, więc masz kompatybilność wsteczną
Chris
72

Możesz użyć Array.concat:

var result = a.concat(b);
Wizja
źródło
16
Array.prototype.concat zwraca nową tablicę.
suricactus,
12
On chce przeforsować istniejącą tablicę, więc Array.prototype.push.apply(arr1, arr2)jest to poprawna odpowiedź, ponieważ używając arr1.concat(arr2)ciebie tworzysz nową tablicę.
suricactus,
3
@suricactus arr1 = arr1.concat(arr2)nie jest wielkim problemem i wygląda na znacznie czystszego. Pchanie do starej tablicy lub wymiana starej tablicy na nową zależy od potrzeb. Jeśli masz do czynienia z elementami powyżej 10 m, wypychanie do starej tablicy będzie działało szybciej, jeśli zarządzasz małymi fragmentami, prawie nie znajdziesz żadnej różnicy prędkości. Obie opcje są całkowicie uzasadnione.
VisioN
5
@YuvalA. prototype.push.applydzwoni tylko pushraz. Powyższe rozróżnienie nie jest konieczne w przypadku szybkości, ale operacja na miejscu vs tworzenie nowej tablicy. Co jeśli miałbym metodę, która wzięła tablicę i miała ją zmodyfikować w miejscu? concatMetoda nie może działać, nawet z kodem VisionN jako że nie będzie modyfikować zmienną do wywołującego funkcję.
coderforlife
1
a = a.concat(b)jest wciąż krótszą składnią niżArray.prototype.push.apply(arr1, arr2)
Aizzat Suhardi
22

Jeśli chcesz alternatywę dla Array.concatECMAScript 2015 (alias ES6, ES2015), która podobnie jak ona nie modyfikuje tablicy, ale zwraca nową tablicę, możesz użyć operatora rozkładania w następujący sposób:

var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);

Zauważ, że różni się to od pushmetody, ponieważ pushmetoda mutuje / modyfikuje tablicę.

Jeśli chcesz sprawdzić, czy niektóre funkcje ES2015 działają w przeglądarce, sprawdź tabelę zgodności Kangax .

Możesz także użyć Babel lub podobnego transpilatora, jeśli nie chcesz czekać na obsługę przeglądarki i chcesz używać ES2015 w produkcji.

Jan
źródło
4

Istnieje wiele odpowiedzi zalecamy stosowania: Array.prototype.push(a, b). To dobry sposób, ALE jeśli będziesz mieć naprawdę duże b, będziesz miał błąd przepełnienia stosu (z powodu zbyt wielu argumentów). Uważaj tutaj.

Zobacz Jaki jest najskuteczniejszy sposób konkatenacji tablic N? po więcej szczegółów.

12kb
źródło
3
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienia, zostaw komentarz pod postem. [Jak napisać dobrą odpowiedź? ] ( stackoverflow.com/help/how-to-answer )
mrun
1
Niestety, nie mogę zostawić komentarza pod odpowiedzią (z wyjątkiem mojej) z powodu niewystarczającej reputacji :). Ale wydaje się, że należy to tutaj wspomnieć, aby mieć pełny przegląd. Czy możesz to dla mnie zrobić? Potem usunę moją odpowiedź.
12kb
0
var a=[];
a.push({
 name_a:"abc",
 b:[]
});

a.b.push({
  name_b:"xyz"
});
Alex Kumbhani
źródło