¿La forma más eficiente de crear una matriz JavaScript llena de ceros?

Resuelto dil asked hace 15 años • 0 respuestas

¿Cuál es la forma más eficiente de crear una matriz llena de ceros de longitud arbitraria en JavaScript?

dil avatar Aug 19 '09 01:08 dil
Aceptado

ES6 presenta Array.prototype.fill. Se puede utilizar así:

new Array(len).fill(0);

No estoy seguro de si es rápido, pero me gusta porque es breve y autodescriptivo.

Todavía no está en IE ( verifique la compatibilidad ), pero hay un polyfill disponible .

Oriol avatar Apr 27 '2014 17:04 Oriol

Aunque este es un hilo viejo, quería agregarle mis 2 centavos. No estoy seguro de qué tan lento/rápido es esto, pero es una frase rápida. Esto es lo que hago:

Si quiero precompletar con un número:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
// [0, 0, 0, 0, 0]

Si quiero precompletar con una cadena:

Array.apply(null, Array(3)).map(String.prototype.valueOf,"hi")
// ["hi", "hi", "hi"]

Otras respuestas han sugerido:

new Array(5+1).join('0').split('')
// ["0", "0", "0", "0", "0"]

pero si quieres 0 (el número) y no "0" (cero dentro de una cadena), puedes hacer:

new Array(5+1).join('0').split('').map(parseFloat)
// [0, 0, 0, 0, 0]
zertosh avatar Dec 06 '2012 01:12 zertosh

En breve

Solución más rápida:

let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;

La solución más corta (útil) (3 veces más lenta para matrices pequeñas, ligeramente más lenta para matrices grandes (más lenta en Firefox))

Array(n).fill(0)

Detalles

Hoy 09.06.2020 realizo pruebas en macOS High Sierra 10.13.6 en los navegadores Chrome 83.0, Firefox 77.0 y Safari 13.1. Pruebo las soluciones elegidas para dos casos de prueba.

  • pequeña matriz - con 10 elementos - puede realizar la prueba AQUÍ
  • matrices grandes, con elementos de 1 millón, puede realizar la prueba AQUÍ

Conclusiones

  • La solución basada en new Array(n)+for(N) es la solución más rápida para matrices pequeñas y grandes (excepto Chrome, pero sigue siendo muy rápida allí) y se recomienda como solución rápida para varios navegadores.
  • La solución basada en new Float32Array(n)(I) devuelve una matriz no típica (por ejemplo, no se puede llamar push(..)a ella), por lo que no comparo sus resultados con otras soluciones; sin embargo, esta solución es entre 10 y 20 veces más rápida que otras soluciones para matrices grandes en todos los navegadores.
  • Las soluciones basadas en for(L,M,N,O) son rápidas para arreglos pequeños.
  • Las soluciones basadas en fill(B,C) son rápidas en Chrome y Safari, pero sorprendentemente más lentas en Firefox para matrices grandes. Son medianamente rápidos para arreglos pequeños.
  • la solución basada en Array.apply(P) arroja un error para matrices grandes

    Mostrar fragmento de código

ingrese la descripción de la imagen aquí

Código y ejemplo

El siguiente código presenta las soluciones utilizadas en las mediciones.

Mostrar fragmento de código

Resultados de ejemplo para Chrome:

ingrese la descripción de la imagen aquí

Kamil Kiełczewski avatar Oct 28 '2018 08:10 Kamil Kiełczewski

Manera elegante de llenar una matriz con valores precalculados

Aquí hay otra forma de hacerlo usando ES6 que nadie ha mencionado hasta ahora:

> Array.from(Array(3), () => 0)
< [0, 0, 0]

Funciona pasando una función de mapa como segundo parámetro de Array.from.

En el ejemplo anterior, el primer parámetro asigna una matriz de 3 posiciones llenas con el valor undefinedy luego la función lambda asigna cada una de ellas al valor 0.

Aunque Array(len).fill(0)es más corto, no funciona si necesita llenar la matriz haciendo algunos cálculos primero (sé que la pregunta no lo pedía, pero mucha gente termina aquí buscando esto) .

Por ejemplo, si necesitas una matriz con 10 números aleatorios:

> Array.from(Array(10), () => Math.floor(10 * Math.random()))
< [3, 6, 8, 1, 9, 3, 0, 6, 7, 1]

Es más conciso (y elegante) que su equivalente:

const numbers = Array(10);
for (let i = 0; i < numbers.length; i++) {
    numbers[i] = Math.round(10 * Math.random());
}

Este método también se puede utilizar para generar secuencias de números aprovechando el parámetro de índice proporcionado en la devolución de llamada:

> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Respuesta adicional: llene una matriz usando Stringrepeat()

Dado que esta respuesta está recibiendo mucha atención, también quería mostrar este genial truco. Aunque no es tan útil como mi respuesta principal, presentaré el repeat()método String aún no muy conocido, pero muy útil. Aquí está el truco:

> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]

Genial, ¿eh? repeat()Es un método muy útil para crear una cadena que es la repetición de la cadena original un número determinado de veces. Después de eso, split()crea una matriz para nosotros, que luego se map()envía a los valores que queremos. Desglosándolo en pasos:

> "?".repeat(10)
< "??????????"

> "?".repeat(10).split("")
< ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]

> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
Lucio Paiva avatar May 22 '2016 17:05 Lucio Paiva