Para duplicar una matriz en JavaScript: ¿cuál de los siguientes es más rápido de usar?
Método de corte
var dup_array = original_array.slice();
For lazo
for(var i = 0, len = original_array.length; i < len; ++i)
dup_array[i] = original_array[i];
Sé que ambas formas solo hacen una copia superficial : si original_array contiene referencias a objetos, los objetos no se clonarán, pero solo se copiarán las referencias y, por lo tanto, ambas matrices tendrán referencias a los mismos objetos. Pero este no es el punto de esta pregunta.
Solo pregunto por la velocidad.
javascript
arrays
duplicates
copy
slice
Marco Demaio
fuente
fuente

Respuestas:
Hay al menos 5 (!) Formas de clonar una matriz:
Ha habido un hilo enorme de BENCHMARKS , que proporciona la siguiente información:
para los navegadores de parpadeo
slice()es el método más rápido,concat()es un poco más lento ywhile loopes 2.4 veces más lento.para otros navegadores
while loopes el método más rápido, ya que esos navegadores no tienen optimizaciones internas parasliceyconcat.Esto sigue siendo cierto en julio de 2016.
A continuación hay scripts simples que puede copiar y pegar en la consola de su navegador y ejecutar varias veces para ver la imagen. Producen milisegundos, menor es mejor.
mientras bucle
rebanada
Tenga en cuenta que estos métodos clonarán el objeto Array en sí, sin embargo, los contenidos de la matriz se copian por referencia y no se clonan en profundidad.
fuente
splicey se sorprenderá (mientras ...)A.map(function(e){return e;});Técnicamente
slicees la forma más rápida. Sin embargo , es aún más rápido si agrega el0índice de inicio.es más rápido que
http://jsperf.com/cloning-arrays/3
fuente
myArray.slice(0,myArray.length-1);más rápido quemyArray.slice(0);?¿qué pasa con es6 way?
fuente
[].concat(_slice.call(arguments))argumentsviene ... Creo que su salida de babel está combinando algunas características diferentes. Es más probable que lo seaarr2 = [].concat(arr1).arr2 = [].conact(arr1)es diferente dearr2 = [...arr1].[...arr1]la sintaxis convertirá el agujero aundefined. Por ejemplo,arr1 = 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'}}]. Sicse cambia el valor en la matriz "duplicada", cambiará en la matriz original, ya que es solo una copia referencial, no un clon.La forma más fácil de clonar profundamente una matriz u objeto:
fuente
undefinedni ningúnfunctions. Ambos serán convertidos anullusted durante elJSON.stringifyproceso. Otras estrategias, como(['cool','array']).slice()no las cambiarán, pero tampoco clonarán objetos en la matriz. Entonces hay una compensación.n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221fuente
Puse una demostración rápida: http://jsbin.com/agugo3/edit
Mis resultados en Internet Explorer 8 son 156, 782 y 750, lo que indicaría que
slicees mucho más rápido en este caso.fuente
a.map(e => e)Es otra alternativa para este trabajo. A partir de hoy.map()es muy rápido (casi tan rápido como.slice(0)) en Firefox, pero no en Chrome.Por otro lado, si una matriz es multidimensional, ya que las matrices son objetos y los objetos son los tipos de referencia, ninguno de los métodos de división o de concat será una cura ... Así que una forma adecuada de la clonación de un array es una invención de
Array.prototype.clone()lo sigue.fuente
🏁 La forma más rápida de clonar una matriz
Hice esta función de utilidad muy simple para probar el tiempo que lleva clonar una matriz. No es 100% confiable, sin embargo, puede darle una idea general de cuánto tiempo lleva clonar una matriz existente:
Y probado enfoque diferente:
ACTUALIZACIÓN :
Nota: de todos ellos, la única forma de clonar en profundidad una matriz es mediante el uso
JSON.parse(JSON.stringify(arr)).Dicho esto, no use lo anterior si su matriz puede incluir funciones, ya que volverá
null.Gracias @GilEpshtain por esta actualización .
fuente
arr => arr.slice()es la más rápida.JSON.parse(JSON.stringify([function(){}]))saldrá[null][...arr]con4.653076171875msChrome y8.565msSafari. El segundo rápido en Chrome es la función de divisiónarr.slice()con6.162109375msy en Safari el segundo es[].concat(arr)con13.018ms.Echa un vistazo a: enlace . No se trata de velocidad, sino de comodidad. Además, como puede ver, solo puede usar el segmento (0) en tipos primitivos .
Para hacer una copia independiente de una matriz en lugar de una copia de la referencia, puede usar el método de división de matriz.
Ejemplo:
Fuente: enlace
fuente
forbucle en la pregunta.Como @Dan dijo "Esta respuesta se vuelve obsoleta rápidamente. Use puntos de referencia para verificar la situación real", hay una respuesta específica de jsperf que no ha tenido una respuesta por sí misma: mientras que :
tuvo 960,589 operaciones / segundo con el segundo puesto
a.concat()en 578,129 operaciones / segundo, que es 60%.Este es el último Firefox (40) de 64 bits.
@aleclarson creó un nuevo punto de referencia más confiable.
fuente
Forma ECMAScript 2015 con el
Spreadoperador:Ejemplos básicos:
Prueba en la consola del navegador:
Referencias
fuente
Depende del navegador. Si mira en la publicación del blog Array.prototype.slice vs creación manual de matriz , hay una guía aproximada para el rendimiento de cada uno:
Resultados:
fuente
argumentsno es una matriz adecuada y está usandocallpara forzar lasliceejecución de la colección Los resultados pueden ser engañosos.Hay una solución mucho más limpia:
Se requiere la verificación de longitud, porque el
Arrayconstructor se comporta de manera diferente cuando se llama con exactamente un argumento.fuente
splice(), tal vez. Pero realmente, aplique y esto es todo menos intuitivo.Array.ofe ignorar la duración:Array.of.apply(Array, array)Recuerde .slice () no funcionará para matrices bidimensionales. Necesitará una función como esta:
fuente
Depende de la longitud de la matriz. Si la longitud de la matriz es <= 1,000,000, los métodos
sliceyconcattardan aproximadamente el mismo tiempo. Pero cuando das un rango más amplio, elconcatmétodo gana.Por ejemplo, intente este código:
Si establece la longitud de original_array en 1,000,000, el
slicemétodo yconcatmétodo demoran aproximadamente el mismo tiempo (3-4 ms, dependiendo de los números aleatorios).Si establece la longitud de original_array en 10,000,000, entonces el
slicemétodo toma más de 60 ms y elconcatmétodo toma más de 20 ms.fuente
dup.pushestá equivocadoa5, en su lugar sedup[i] =debe usarUna solución simple:
fuente
Entonces, para evitar que ocurran estos escenarios, use
fuente
cloneNums[0][0]en su ejemplo propagó el cambionums[0][0], pero eso es porquenums[0][0]efectivamente es un objeto cuya referencia es copiadacloneNumspor el operador de propagación. Todo lo que quiere decir, este comportamiento no afectará el código donde estamos copiando por valor (int, string, etc. literales).Tiempo de referencia!
Mis resultados:
Chrome (motor V8):
Firefox (motor SpiderMonkey):
fuente
Formas rápidas de duplicar una matriz en JavaScript en orden:
#1: array1copy = [...array1];#2: array1copy = array1.slice(0);#3: array1copy = array1.slice();Si sus objetos de matriz contienen algún contenido no serializable JSON (funciones, Number.POSITIVE_INFINITY, etc.), mejor usar
array1copy = JSON.parse(JSON.stringify(array1))fuente
Puedes seguir este código. Forma inmutable matriz clon. Esta es la manera perfecta de clonar en matriz
fuente
En ES6, simplemente puede utilizar la sintaxis Spread .
Ejemplo:
Tenga en cuenta que el operador de propagación genera una matriz completamente nueva, por lo que modificar una no afectará a la otra.
Ejemplo:
fuente