So duplizieren Sie ein Array in JavaScript: Welche der folgenden Optionen ist schneller zu verwenden?
Schnittmethode
var dup_array = original_array.slice();
For
Schleife
for(var i = 0, len = original_array.length; i < len; ++i)
dup_array[i] = original_array[i];
Ich weiß, dass beide Methoden nur eine flache Kopie erstellen: Wenn original_array Verweise auf Objekte enthält, werden Objekte nicht geklont, sondern nur die Verweise werden kopiert, und daher haben beide Arrays Verweise auf dieselben Objekte. Dies ist jedoch nicht der Punkt dieser Frage.
Ich frage nur nach Geschwindigkeit.
javascript
arrays
duplicates
copy
slice
Marco Demaio
quelle
quelle
Antworten:
Es gibt mindestens 5 (!) Möglichkeiten, ein Array zu klonen:
Es gab einen riesigen BENCHMARKS-Thread mit folgenden Informationen:
Für Blink- Browser
slice()
ist dies die schnellste Methode,concat()
etwas langsamer undwhile loop
2,4-mal langsamer.für andere Browser
while loop
ist die schnellste Methode, da diese Browser keine internen Optimierungen fürslice
und habenconcat
.Dies gilt auch im Juli 2016.
Im Folgenden finden Sie einfache Skripte, die Sie kopieren, in die Konsole Ihres Browsers einfügen und mehrmals ausführen können, um das Bild anzuzeigen. Sie geben Millisekunden aus, niedriger ist besser.
while-Schleife
Scheibe
Beachten Sie, dass diese Methoden das Array-Objekt selbst klonen. Der Inhalt des Arrays wird jedoch als Referenz kopiert und nicht tief geklont.
quelle
splice
und Sie werden überrascht sein (während ...)A.map(function(e){return e;});
Technisch
slice
ist der schnellste Weg. Allerdings ist es noch schneller , wenn Sie das Add -0
Index beginnen.ist schneller als
http://jsperf.com/cloning-arrays/3
quelle
myArray.slice(0,myArray.length-1);
schneller alsmyArray.slice(0);
?was ist mit es6 weg?
quelle
[].concat(_slice.call(arguments))
arguments
Ich bin mir nicht sicher, woher es kommt ... Ich denke, Ihre Babel-Ausgabe vereint ein paar verschiedene Funktionen. Es ist wahrscheinlicherarr2 = [].concat(arr1)
.arr2 = [].conact(arr1)
unterscheidet sich vonarr2 = [...arr1]
.[...arr1]
Die Syntax konvertiert das Loch inundefined
. Zum Beispielarr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3
.n = 1000*1000; start = + new Date(); a = Array(n); b = [...a]; console.log(new Date() - start); // 168
[{a: 'a', b: {c: 'c'}}]
. Wennc
der Wert im "duplizierten" Array geändert wird, ändert er sich im ursprünglichen Array, da es sich nur um eine referenzielle Kopie handelt, nicht um einen Klon.Der einfachste Weg, ein Array oder Objekt tief zu klonen:
quelle
undefined
keinefunction
s enthalten kann . Beide werdennull
während desJSON.stringify
Vorgangs für Sie konvertiert . Andere Strategien, z. B.(['cool','array']).slice()
ändern sie nicht, klonen aber auch keine Objekte innerhalb des Arrays. Es gibt also einen Kompromiss.n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221
quelle
Ich habe eine kurze Demo zusammengestellt: http://jsbin.com/agugo3/edit
Meine Ergebnisse in Internet Explorer 8 sind 156, 782 und 750, was darauf hinweist, dass dies
slice
in diesem Fall viel schneller ist.quelle
a.map(e => e)
ist eine weitere Alternative für diesen Job. Ab heute.map()
ist.slice(0)
in Firefox sehr schnell (fast so schnell wie ), aber nicht in Chrome.Wenn andererseits ein Array mehrdimensional ist, da Arrays Objekte und Objekte Referenztypen sind, ist keine der Slice- oder Concat-Methoden eine Heilung ... Ein geeigneter Weg zum Klonen eines Arrays ist also eine Erfindung von
Array.prototype.clone()
as folgt.quelle
🏁 Schnellster Weg zum Klonen eines Arrays
Ich habe diese sehr einfache Dienstprogrammfunktion erstellt, um die Zeit zu testen, die zum Klonen eines Arrays benötigt wird. Es ist nicht 100% zuverlässig, kann Ihnen jedoch eine umfassende Vorstellung davon geben, wie lange es dauert, ein vorhandenes Array zu klonen:
Und verschiedene Ansätze getestet:
UPDATE :
Hinweis: Von allen ist die einzige Möglichkeit, ein Array tief zu klonen, die Verwendung von
JSON.parse(JSON.stringify(arr))
.Verwenden Sie das oben Gesagte jedoch nicht, wenn Ihr Array möglicherweise Funktionen enthält, die zurückgegeben werden
null
.Vielen Dank an @GilEpshtain für dieses Update .
quelle
arr => arr.slice()
der schnellste ist.JSON.parse(JSON.stringify([function(){}]))
wird ausgegeben[null]
[...arr]
mit4.653076171875ms
in Chrome und8.565ms
in Safari. Das zweite schnelle in Chrome ist die Slice-Funktionarr.slice()
mit6.162109375ms
und in Safari das zweite[].concat(arr)
mit13.018ms
.Schauen Sie sich an: Link . Es geht nicht um Geschwindigkeit, sondern um Komfort. Außerdem können Sie, wie Sie sehen, Slice (0) nur für primitive Typen verwenden .
Sie können die Array-Slice-Methode verwenden, um eine unabhängige Kopie eines Arrays zu erstellen, anstatt eine Kopie der Referenz darauf.
Beispiel:
Quelle: Link
quelle
for
Schleife in der Frage.Wie @Dan sagte "Diese Antwort ist schnell veraltet. Verwenden Sie Benchmarks , um die tatsächliche Situation zu überprüfen", gibt es eine spezifische Antwort von jsperf, die keine Antwort für sich hatte: while :
hatte 960.589 Ops / Sek. mit dem zweiten Platz
a.concat()
bei 578.129 Ops / Sek., was 60% entspricht.Dies ist das neueste 64-Bit-Firefox (40).
@aleclarson hat einen neuen, zuverlässigeren Benchmark erstellt.
quelle
ECMAScript 2015 Weg mit dem
Spread
Betreiber:Grundlegende Beispiele:
Versuchen Sie es in der Browserkonsole:
Verweise
quelle
Das hängt vom Browser ab. Wenn Sie sich den Blog-Beitrag Array.prototype.slice im Vergleich zur manuellen Array-Erstellung ansehen , gibt es eine grobe Anleitung zur Leistung der einzelnen:
Ergebnisse:
quelle
arguments
ist kein richtiges Array und ercall
erzwingtslice
das Ausführen der Sammlung. Ergebnisse können irreführend sein.Es gibt eine viel sauberere Lösung:
Die Längenprüfung ist erforderlich, da sich der
Array
Konstruktor anders verhält, wenn er mit genau einem Argument aufgerufen wird.quelle
splice()
vielleicht. Aber wirklich, bewerben Sie sich und das ist alles andere als intuitiv.Array.of
die Länge verwenden und ignorieren:Array.of.apply(Array, array)
Denken Sie daran, dass .slice () für zweidimensionale Arrays nicht funktioniert. Sie benötigen eine Funktion wie diese:
quelle
Dies hängt von der Länge des Arrays ab. Wenn die Arraylänge ist <= 1000000, die
slice
undconcat
nehmen Methoden etwa zur gleichen Zeit. Wenn Sie jedoch einen größeren Bereichconcat
angeben, gewinnt die Methode.Versuchen Sie zum Beispiel diesen Code:
Wenn Sie die Länge von original_array auf 1.000.000 festlegen, dauern
slice
Methode undconcat
Methode ungefähr dieselbe Zeit (3-4 ms, abhängig von den Zufallszahlen).Wenn Sie die Länge von original_array auf 10.000.000 festlegen,
slice
dauert die Methode über 60 ms und dieconcat
Methode über 20 ms.quelle
dup.push
ist falsch ina5
,dup[i] =
sollte stattdessen verwendet werdenEine einfache Lösung:
quelle
Um diese Szenarien zu vermeiden, verwenden Sie
quelle
cloneNums[0][0]
in Ihrem Beispiel die Änderung weitergegeben hatnums[0][0]
- aber das liegt daran, dassnums[0][0]
es sich tatsächlich um ein Objekt handelt, in dessen ReferenzcloneNums
der Spread-Operator kopiert wird. Das heißt, dieses Verhalten wirkt sich nicht auf Code aus, bei dem nach Wert kopiert wird (Int-, String- usw. Literale).Benchmark-Zeit!
Meine Ergebnisse:
Chrom (V8-Motor):
Firefox (SpiderMonkey Engine):
quelle
Schnelle Möglichkeiten zum Duplizieren eines Arrays in JavaScript in der folgenden Reihenfolge:
#1: array1copy = [...array1];
#2: array1copy = array1.slice(0);
#3: array1copy = array1.slice();
Wenn Ihre Array-Objekte nicht serialisierbaren JSON-Inhalt (Funktionen, Number.POSITIVE_INFINITY usw.) enthalten, ist dies besser zu verwenden
array1copy = JSON.parse(JSON.stringify(array1))
quelle
Sie können diesem Code folgen. Unveränderlicher Weg Array-Klon. Dies ist der perfekte Weg zum Klonen von Arrays
quelle
In ES6 können Sie einfach die Spread-Syntax verwenden .
Beispiel:
Bitte beachten Sie, dass der Spread-Operator ein völlig neues Array generiert, sodass sich das Ändern eines Arrays nicht auf das andere auswirkt.
Beispiel:
quelle