objetos matriz length especifico eliminar elementos elemento ejemplos contar bidimensional array agregar javascript arrays jslint

matriz - ¿Cómo inicializar la longitud de un array en javascript?



eliminar un elemento especifico de un array javascript (16)

  1. ¿Por qué quieres inicializar la longitud? Teóricamente no hay necesidad de esto. Incluso puede resultar en un comportamiento confuso, porque todas las pruebas que usan la length para averiguar si una matriz está vacía o no informarán que la matriz no está vacía.
    Some tests muestran que establecer la longitud inicial de las matrices grandes puede ser más eficiente si la matriz se llena después, pero la ganancia de rendimiento (si existe) parece diferir de un navegador a otro.

  2. A jsLint no le gusta la new Array() porque el constructor es ambiguo.

    new Array(4);

    crea una matriz vacía de longitud 4. Pero

    new Array(''4'');

    crea una matriz que contiene el valor ''4'' .

Con respecto a su comentario: En JS no necesita inicializar la longitud de la matriz. Crece dinámicamente. Puede almacenar la longitud en alguna variable, por ejemplo,

var data = []; var length = 5; // user defined length for(var i = 0; i < length; i++) { data.push(createSomeObject()); }

La mayoría de los tutoriales que he leído en matrices en JavaScript (incluyendo w3schools y devguru ) sugieren que puedes inicializar una matriz con una cierta longitud pasando un número entero al constructor de Arrays usando la var test = new Array(4); sintaxis.

Después de usar esta sintaxis generosamente en mis archivos js, ejecuté uno de los archivos a través de jsLint , y me jsLint :

Error: Problema en la línea 1 carácter 22: Se esperaba '')'' y en su lugar vio ''4''.
var prueba = nueva matriz (4);
Problema en la línea 1 carácter 23: Se esperaba '';'' y en su lugar vio '')''.
var prueba = nueva matriz (4);
Problema en la línea 1 carácter 23: Se esperaba un identificador y en su lugar se vio '')''.

Después de leer la explicación de jsLint de su comportamiento , parece que a jsLint realmente no le gusta la new Array() sintaxis new Array() , y en su lugar prefiere [] al declarar arrays.

Así que tengo un par de preguntas. Primero por que ¿Estoy corriendo algún riesgo usando la new Array() sintaxis new Array() lugar? ¿Hay incompatibilidades de navegador de las que debería estar enterado? Y segundo, si cambio a la sintaxis del corchete, ¿hay alguna manera de declarar una matriz y establecer su longitud en una sola línea, o tengo que hacer algo como esto?

var test = []; test.length = 4;


(Esto fue probablemente mejor como un comentario, pero se hizo demasiado largo)

Entonces, después de leer esto, tenía curiosidad por saber si la asignación previa era en realidad más rápida, porque en teoría debería serlo. Sin embargo, este blog dio algunos consejos que lo desaconsejaron http://www.html5rocks.com/en/tutorials/speed/v8/ .

Así que todavía no estoy seguro, lo puse a prueba. Y resulta que, de hecho, parece ser más lento.

var time = Date.now(); var temp = []; for(var i=0;i<100000;i++){ temp[i]=i; } console.log(Date.now()-time); var time = Date.now(); var temp2 = new Array(100000); for(var i=0;i<100000;i++){ temp2[i] = i; } console.log(Date.now()-time);

Este código produce lo siguiente después de algunas ejecuciones ocasionales:

$ node main.js 9 16 $ node main.js 8 14 $ node main.js 7 20 $ node main.js 9 14 $ node main.js 9 19


Aquí hay otra solución.

var arr = Array.apply( null, { length: 4 } ); arr; // [undefined, undefined, undefined, undefined] (in Chrome) arr.length; // 4

El primer argumento de apply() es un enlace de este objeto, que no nos importa aquí, por lo que lo establecemos en null .

Array.apply(..) llama a la función Array(..) y distribuye el valor del objeto { length: 3 } como sus argumentos.


Como se explicó anteriormente, usar un new Array(size) es algo peligroso. En lugar de usarlo directamente, colóquelo dentro de una "función de creador de matriz". Puede asegurarse fácilmente de que esta función esté libre de errores y evitar el peligro de llamar directamente al new Array(size) . Además, puede darle un valor inicial predeterminado opcional. Esta función createArray hace exactamente eso:

function createArray(size, defaultVal) { var arr = new Array(size); if (arguments.length == 2) { // optional default value for (int i = 0; i < size; ++i) { arr[i] = defaultVal; } } return arr; }


Con ES2015 .fill() ahora puede simplemente hacer:

// `n` is the size you want to initialize your array // `0` is what the array will be filled with (can be any other value) Array(n).fill(0)

Lo que es mucho más conciso que Array.apply(0, new Array(n)).map(i => value)

Es posible eliminar el 0 en .fill() y ejecutar sin argumentos, lo que llenará la matriz con undefined . ( Sin embargo, esto fallará en Typescript )


ES6 presenta Array.from que le permite crear una Array partir de cualquier objeto "similar a una matriz" o iterables :

Array.from({length: 10}, (x, i) => i); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

En este caso {length: 10} representa la definición mínima de un objeto "similar a una matriz" : un objeto vacío con solo una propiedad de length definida.

Array.from permite que un segundo argumento se Array.from sobre la matriz resultante.


El constructor de arreglos tiene una sintaxis ambigua , y JSLint solo lastima tus sentimientos después de todo.

Además, su código de ejemplo está roto, la segunda declaración var generará un SyntaxError . Está configurando la length de la propiedad de la test matriz, por lo que no hay necesidad de otra var .

En cuanto a sus opciones, array.length es el único "limpio". La pregunta es, ¿por qué necesita establecer el tamaño en primer lugar? Trate de refactorizar su código para deshacerse de esa dependencia.


El más corto:

[...Array(1000)]


Esto inicializará la propiedad length a 4:

var x = [,,,,];


La razón por la que no debe usar la new Array se demuestra en este código:

var Array = function () {}; var x = new Array(4); alert(x.length); // undefined...

Algún otro código podría meterse con la variable Array. Sé que es un poco extraño que alguien escriba ese código, pero aún así ...

Además, como dijo Felix King, la interfaz es un poco inconsistente y podría dar lugar a algunos errores muy difíciles de localizar.

Si quisiera una matriz con longitud = x, rellenada con indefinido (como haría una new Array(x) ), podría hacer esto:

var x = 4; var myArray = []; myArray[x - 1] = undefined; alert(myArray.length); // 4


Me sorprende que no se haya sugerido una solución funcional que le permita establecer la longitud en una línea. Lo siguiente se basa en UnderscoreJS:

var test = _.map(_.range(4), function () { return undefined; }); console.log(test.length);

Por las razones mencionadas anteriormente, evitaría hacer esto a menos que quisiera inicializar la matriz a un valor específico. Es interesante notar que hay otras bibliotecas que implementan el rango, incluyendo Lo-dash y Lazy, que pueden tener diferentes características de rendimiento.


Por favor, la gente no abandona sus viejos hábitos todavía. Hay una gran diferencia en la velocidad entre la asignación de memoria una vez que se trabaja con las entradas en esa matriz (como en la antigüedad), y la asignación muchas veces a medida que crece una matriz (que es inevitablemente lo que hace el sistema bajo el capó con otros métodos sugeridos) .

Nada de esto importa, por supuesto, hasta que quiera hacer algo genial con matrices más grandes. Entonces lo hace.

Ya que parece que todavía no hay ninguna opción en JS para configurar la capacidad inicial de una matriz, uso lo siguiente ...

var newArrayWithSize = function(size) { this.standard = this.standard||[]; for (var add = size-this.standard.length; add>0; add--) { this.standard.push(undefined);// or whatever } return this.standard.slice(0,size); }

Hay compensaciones involucradas:

  • Este método toma tanto tiempo como los otros para la primera llamada a la función, pero muy poco tiempo para llamadas posteriores (a menos que se solicite una matriz más grande).
  • La matriz standard reserva permanentemente tanto espacio como la matriz más grande que ha solicitado.

Pero si encaja con lo que estás haciendo, puede haber una recompensa. Tiempo informal pone

for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}

a bastante velocidad (unos 50ms para los 10000 dado que con n = 1000000 tomó unos 5 segundos), y

for (var n=10000;n>0;n--) { var b = [];for (var add=10000;add>0;add--) { b.push(undefined); } }

a más de un minuto (aproximadamente 90 segundos para los 10000 en la misma consola de Chrome, o aproximadamente 2000 veces más lento). Esa no será solo la asignación, sino también los 10000 impulsos, para bucle, etc.


Puede establecer la longitud de la matriz utilizando array.length = youValue

Asi seria

var myArray = []; myArray.length = yourValue;


[...Array(6)].map(x=>0); // [0, 0, 0, 0, 0, 0]

O

Array(6).fill(0); // [0, 0, 0, 0, 0, 0]

O

Array(6).fill(null).map( (x,i) => i ); // [0, 1, 2, 3, 4, 5]

( escritura a máquina segura )

Creando arrays anidados

Al crear una matriz 2D con el fill intuitiva debe crear nuevas instancias. Pero lo que realmente ocurrirá es que se almacenará la misma matriz como referencia.

var a = Array(3).fill([6]); // [[6], [6], [6]] a[ 0 ].push( 9 ); // [[6,9], [6,9], [6,9]]

Solución

var a = [...Array(3)].map(x=>[]); a[ 0 ].push( 4, 2 ); // [[4,2], [ ], [ ]]

Así que una matriz de 3x2 se verá algo como esto:

[...Array(3)].map(x=>Array(2).fill(0)); // [ [0,0] , // [0,0] , // [0,0] ]


var arr=[]; arr[5]=0; alert("length="+arr.length); // gives 6


  • Array(5) le da una matriz con longitud 5 pero sin valores, por lo que no puede iterar sobre ella.

  • Array.apply(null, Array(5)).map(function () {}) le proporciona un array con una longitud de 5 y undefined como valores, ahora se puede iterar.

  • Array.apply(null, Array(5)).map(function (x, i) { return i; }) le da una matriz con longitud 5 y valores 0,1,2,3,4.

  • Array(5).forEach(alert) no hace nada, Array.apply(null, Array(5)).forEach(alert) le da 5 alertas

  • ES6 nos da Array.from . Array.from ahora también puede usar Array.from(Array(5)).forEach(alert)

  • Si desea inicializar con un cierto valor, estos son buenos saber ...
    Array.from(''abcde'') , Array.from(''x''.repeat(5))
    o Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]