Mam tablicę JavaScript, dataArray
którą chcę wcisnąć do nowej tablicy newArray
. Tyle że nie chcę newArray[0]
być dataArray
. Chcę wepchnąć wszystkie elementy do nowej tablicy:
var newArray = [];
newArray.pushValues(dataArray1);
newArray.pushValues(dataArray2);
// ...
lub nawet lepiej:
var newArray = new Array (
dataArray1.values(),
dataArray2.values(),
// ... where values() (or something equivalent) would push the individual values into the array, rather than the array itself
);
Tak więc teraz nowa tablica zawiera wszystkie wartości poszczególnych tablic danych. Czy jest jakiś skrót, który jest pushValues
dostępny, więc nie muszę powtarzać każdego z osobna dataArray
, dodając elementy jeden po drugim?
javascript
arrays
bba
źródło
źródło
Odpowiedzi:
Użyj funkcji concat , tak jak poniżej :
Wartość
newArray
będzie[1, 2, 3, 4]
(arrayA
iarrayB
pozostanie niezmieniona;concat
tworzy i zwraca nową tablicę dla wyniku).źródło
Google Chrome
: Szybki (concat = zwycięzca)Opera
: szybki (concat = zwycięzca)IE
: wolniej (concat = zwycięzca)Firefox
: powolny (push.apply = zwycięzca, jeszcze 10 razy wolniej niż concat Chrome) ... mówić o złej implementacji silnika JS .push
nie spowoduje spłaszczenia tablicy wartości.concat
osiąga to, czego wymaga pytanie.Pod warunkiem, że tablice nie są duże (patrz zastrzeżenie poniżej), możesz użyć
push()
metody tablicy, do której chcesz dołączyć wartości.push()
może przyjmować wiele parametrów, dzięki czemu można użyć tejapply()
metody do przekazania tablicy wartości, które mają zostać przekazane jako lista parametrów funkcji. Ma to tę zaletę,concat()
że zamiast dodawać nowe elementy do tablicy zamiast tworzyć nową tablicę.Wydaje się jednak, że w przypadku dużych tablic (rzędu 100 000 lub więcej członków) ta sztuczka może się nie powieść . W przypadku takich tablic lepszym rozwiązaniem jest użycie pętli. Szczegółowe informacje można znaleźć na stronie https://stackoverflow.com/a/17368101/96100 .
Możesz uogólnić to na funkcję:
... lub dodaj go do
Array
prototypu:... lub emuluj oryginalną
push()
metodę, dopuszczając wiele parametrów, wykorzystując fakt, żeconcat()
np.push()
pozwala na wiele parametrów:Oto wersja ostatniego przykładu oparta na pętli, odpowiednia dla dużych tablic i wszystkich głównych przeglądarek, w tym IE <= 8:
źródło
newArray.push.apply(newArray, dataArray1);
daje to samo, coArray.prototype.push.applay(newArray,dataArra1);
Array.prototype.concat
nie jest złe, raczej jest po prostu źle zrozumiane, a czasem niewłaściwie używane. W tych okolicznościach jest to tylko niezrozumiane, ale nie nadużywane.Dodam jeszcze jedną odpowiedź „na przyszłość”
W ECMAScript 6 możesz użyć składni Spread :
Składnia rozprzestrzeniania się nie jest jeszcze dostępna we wszystkich głównych przeglądarkach. Bieżącą kompatybilność można znaleźć w tej (stale aktualizowanej) tabeli zgodności .
Możesz jednak użyć składni rozprzestrzeniania w Babel.js .
edytować:
Zobacz odpowiedź Jacka Giffina poniżej, aby uzyskać więcej komentarzy na temat wydajności. Wydaje się, że konkat jest jeszcze lepszy i szybszy niż operator spreadu.
źródło
newArray.apply(newArray, dataArray1)
.Znalazłem elegancki sposób z MDN
Lub możesz użyć
spread operator
funkcji ES6:źródło
Czy to rozwiązuje twój problem?
źródło
Najprostsze wydaje mi się:
Ponieważ „push” przyjmuje zmienną liczbę argumentów, możesz użyć
apply
metodypush
funkcji do wypchnięcia wszystkich elementów innej tablicy. Konstruuje wywołanie push, używając pierwszego argumentu (tutaj „newArray”) jako „this”, a elementów tablicy jako pozostałych argumentów.slice
W pierwszym piśmie dostaje kopię pierwszej tablicy, więc nie modyfikować.Aktualizacja Jeśli używasz wersji javascript z dostępnym plasterkiem, możesz uprościć
push
wyrażenie do:źródło
Poniższa funkcja nie ma problemu z długością tablic i działa lepiej niż wszystkie sugerowane rozwiązania:
niestety, jspref odmawia przyjęcia moich zgłoszeń, więc oto wyniki przy użyciu benchmark.js
gdzie
dla pętli i push jest:
Push Zastosuj:
operator rozrzutu:
i wreszcie „ustawiona długość i pętla” to powyższa funkcja
źródło
𝗥𝗲𝘀𝗲𝗮𝗿𝗰𝗵 𝗔𝗻𝗱 𝗥𝗲𝘀𝘂𝗹𝘁𝘀
W rzeczywistości przeprowadzany jest test wydajności w jsperf i sprawdzanie niektórych rzeczy w konsoli. Do badań wykorzystano stronę irt.org . Poniżej znajduje się zbiór wszystkich tych źródeł razem oraz przykładowa funkcja na dole.
Jak widać powyżej, argumentowałbym, że Concat prawie zawsze jest drogą do osiągnięcia zarówno wydajności, jak i zdolności do zachowania rzadkości zapasowych macierzy. Następnie, dla podobnych do tablicy (takich jak DOMNodeLists, jak
document.body.children
), zaleciłbym użycie pętli for, ponieważ jest ona zarówno 2. najbardziej wydajną, jak i jedyną inną metodą, która zachowuje rzadkie tablice. Poniżej szybko przejrzymy, co oznaczają rzadkie tablice i tablice-lubi wyjaśnić zamieszanie.𝗧𝗵𝗲 𝗙𝘂𝘁𝘂𝗿𝗲
Na początku niektórzy ludzie mogą myśleć, że jest to przypadek i że producenci przeglądarek w końcu zaczną optymalizować Array.prototype.push, aby być wystarczająco szybkim, aby pokonać Array.prototype.concat. ŹLE! Array.prototype.concat zawsze będzie szybszy (przynajmniej w zasadzie), ponieważ jest to zwykłe kopiowanie i wklejanie danych. Poniżej znajduje się uproszczony perswaado-wizualny schemat tego, jak może wyglądać implementacja tablicy 32-bitowej (pamiętaj, że prawdziwe implementacje są dużo bardziej skomplikowane)
Jak widać powyżej, wszystko, co musisz zrobić, aby skopiować coś takiego, jest prawie tak proste, jak skopiowanie bajtu po bajcie. Dzięki Array.prototype.push.apply jest to znacznie więcej niż zwykłe kopiowanie i wklejanie danych. „.Apply” musi sprawdzić każdy indeks w tablicy i przekonwertować go na zestaw argumentów przed przekazaniem go do Array.prototype.push. Następnie Array.prototype.push musi dodatkowo przydzielać więcej pamięci za każdym razem, a (w przypadku niektórych implementacji przeglądarki) może nawet przeliczyć niektóre dane wyszukiwania pozycji dla rzadkości.
Alternatywnym sposobem myślenia o tym jest to. Pierwszy z nich to duży stos zszytych ze sobą papierów. Druga tablica źródłowa to także kolejny duży stos papierów. Czy byłoby to dla ciebie szybsze
W powyższej analogii opcja nr 1 reprezentuje Array.prototype.concat, a nr 2 reprezentuje Array.prototype.push.apply. Przetestujmy to z podobnym JSperf, różniącym się tylko tym, że ten testuje metody na rzadkich tablicach, a nie na stałych tablicach. Można go znaleźć tutaj .
Dlatego opieram swój przypadek, że przyszłość wydajności dla tego konkretnego przypadku użycia nie leży w Array.prototype.push, ale raczej w Array.prototype.concat.
𝗖𝗹𝗮𝗿𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀
𝗦𝗽𝗮𝗿𝗲 𝗔𝗿𝗿𝗮𝘆𝘀
Gdy po prostu brakuje niektórych członków tablicy. Na przykład:
Alternatywnie, javascript pozwala łatwo inicjować zapasowe tablice.
𝗔𝗿𝗿𝗮𝘆-𝗟𝗶𝗸𝗲𝘀
Tablicowy to obiekt, który ma przynajmniej
length
właściwość, ale nie został zainicjowany przy pomocynew Array
lub[]
; Na przykład poniższe obiekty są klasyfikowane jako tablicowe.Obserwuj, co się dzieje, używając metody, która wymusza zamiany tablic na tablice takie jak plasterek.
Pokaż fragment kodu
Obserwuj, co się dzieje, używając metody, która nie zmusza tablic do tablic takich jak concat.
Pokaż fragment kodu
źródło
Za pomocą JavaScript ES6 możesz użyć operatora ... jako operatora rozkładania, który zasadniczo przekształci tablicę w wartości. Następnie możesz zrobić coś takiego:
Chociaż składnia jest zwięzła, nie wiem, jak to działa wewnętrznie i jakie są konsekwencje wydajności dla dużych tablic.
źródło
Array.push.apply
techniki.Oto sposób ES6
źródło
Istnieje wiele odpowiedzi na temat Array.prototype.push.apply . Oto wyraźny przykład:
Jeśli masz składnię ES6:
źródło
Jeśli chcesz zmodyfikować oryginalną tablicę, możesz rozłożyć i wcisnąć:
Jeśli chcesz się upewnić, że w
source
tablicy znajdują się tylko elementy tego samego typu (na przykład nie mieszając liczb i ciągów znaków), użyj TypeScript.źródło
Mamy dwie tablice a i b. kod, który tu zrobił to tablica, wartość jest wypychana do tablicy b.
źródło
Spróbuj tego:
źródło
zamiast funkcji push () użyj funkcji konkat dla IE. przykład,
źródło
To jest działający kod i działa dobrze:
źródło