Tengo una matriz creada con este código:
var widthRange = new Array();
widthRange[46] = { min:0, max:52 };
widthRange[66] = { min:52, max:70 };
widthRange[90] = { min:70, max:94 };
Quiero obtener cada uno de los valores 46, 66, 90 en un bucle. Lo intenté, for (var key in widthRange)
pero esto me da un montón de propiedades adicionales (supongo que son funciones en el objeto). No puedo usar un bucle for regular ya que los valores no son secuenciales.
javascript
arrays
key
Cabra descontenta
fuente
fuente
Array.prototype.forEach
. LlamarObject.keys
a una matriz no funciona bien porque los navegadores no la optimizan.for(var key in array)
es malo porque atraviesa el prototipo y encadena cada tecla numérica que encuentra (convertir dobles a base10 es muy lento).forEach
, sin embargo, fue diseñado exactamente con el propósito de iterar matrices dispersas y le dará a su código un rendimiento excelente en comparación con otras solucionesRespuestas:
Debe llamar a la
hasOwnProperty
función para verificar si la propiedad está realmente definida en el objeto en sí (a diferencia de su prototipo), así:for (var key in widthRange) { if (key === 'length' || !widthRange.hasOwnProperty(key)) continue; var value = widthRange[key]; }
Tenga en cuenta que necesita una verificación separada para
length
.Sin embargo, no debería utilizar una matriz aquí en absoluto; debería utilizar un objeto normal. Todos los objetos de Javascript funcionan como matrices asociativas.
Por ejemplo:
var widthRange = { }; //Or new Object() widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 };
fuente
length
? ¿No está marcado como[[DontEnum]]
en todos los navegadores?Las claves en cadena se pueden consultar con
Object.keys(array)
.fuente
array.keys()
no devolvió nada.Si está realizando algún tipo de manipulación o inspección de matriz / colección, le recomiendo usar Underscore.js . Es pequeño, bien probado y le ahorrará días / semanas / años de dolor de cabeza de javascript. Aquí está su función de teclas:
Llaves
Recupera todos los nombres de las propiedades del objeto.
_.keys({one : 1, two : 2, three : 3}); => ["one", "two", "three"]
fuente
Digamos que su matriz se ve como
arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ]
(o posiblemente otras claves) que podría hacerarr.map((o) => { return Object.keys(o) }).reduce((prev, curr) => { return prev.concat(curr) }).filter((col, i, array) => { return array.indexOf(col) === i });
["a", "b", "c"]
fuente
for (var i = 0; i < widthRange.length; ++i) { if (widthRange[i] != null) { // do something } }
Realmente no puede obtener solo las claves que ha configurado porque no es así como funciona una matriz. Una vez que configura el elemento 46, también tiene configurado de 0 a 45 (aunque son nulos).Siempre puedes tener dos matrices:
var widthRange = [], widths = [], newVal = function(n) { widths.push(n); return n; }; widthRange[newVal(26)] = { whatever: "hello there" }; for (var i = 0; i < widths.length; ++i) { doSomething(widthRange[widths[i]]); }
edita bien puede ser que aquí estoy todo mojado ...
fuente
widthRange.map(function(_, i) { return i });
o
widthRange.map((_, i) => i);
fuente
Tu ejemplo original funciona bien para mí:
<html> <head> </head> <body> <script> var widthRange = new Array(); widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 }; var i = 1; for (var key in widthRange) { document.write("Key #" + i + " = " + key + "; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />"); i++; } </script> </html>
Resultados en el navegador (Firefox 3.6.2 en Windows XP):
Key #1 = 46; min/max = 0/52 Key #2 = 66; min/max = 52/70 Key #3 = 90; min/max = 70/94
fuente
Creo que deberías usar un Object (
{}
) y no una matriz ([]
) para esto.Un conjunto de datos está asociado con cada clave. Grita por usar un objeto. Hacer:
var obj = {}; obj[46] = { sel:46, min:0, max:52 }; obj[666] = { whatever:true }; // This is what for..in is for for (var prop in obj) { console.log(obj[prop]); }
Quizás algunas cosas de utilidad como esta puedan ayudar:
window.WidthRange = (function () { var obj = {}; return { getObj: function () {return obj;} , add: function (key, data) { obj[key] = data; return this; // enabling chaining } } })(); // Usage (using chaining calls): WidthRange.add(66, {foo: true}) .add(67, {bar: false}) .add(69, {baz: 'maybe', bork:'absolutely'}); var obj = WidthRange.getObj(); for (var prop in obj) { console.log(obj[prop]); }
fuente
Parece funcionar.
var widthRange = new Array(); widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 }; for (var key in widthRange) { document.write(widthRange[key].sel + "<br />"); document.write(widthRange[key].min + "<br />"); document.write(widthRange[key].max + "<br />"); }
fuente
Escribí una función que funciona bien con cada instancia de Objects (las matrices son esas).
Object.prototype.toArray = function() { if(!this) { return null; } var c = []; for (var key in this) { if ( ( this instanceof Array && this.constructor === Array && key === 'length' ) || !this.hasOwnProperty(key) ) { continue; } c.push(this[key]); } return c; };
Uso:
var a = [ 1, 2, 3 ]; a[11] = 4; a["js"] = 5; console.log(a.toArray()); var b = { one: 1, two: 2, three: 3, f: function() { return 4; }, five: 5 }; b[7] = 7; console.log(b.toArray());
Salida:
> [ 1, 2, 3, 4, 5 ] > [ 7, 1, 2, 3, function () { return 4; }, 5 ]
Puede ser útil para cualquiera.
fuente
... ????
Alternativamente, si tiene una lista de elementos que desea utilizar ...
var range = [46, 66, 90] , widthRange=[] , write=[]; widthRange[46] = { min:0, max:52 }; widthRange[66] = { min:52, max:70 }; widthRange[90] = { min:70, max:94 }; for(var x=0; x<range.length; x++){var key, wr; key = range[x]; wr = widthRange[key] || false; if(wr===false){continue;} write.push(['key: #',key, ', min: ', wr.min, 'max:', wr.max].join('')); }
fuente
Para sus datos de entrada:
let widthRange = new Array() widthRange[46] = { min:0, max:52 } widthRange[61] = { min:52, max:70 } widthRange[62] = { min:52, max:70 } widthRange[63] = { min:52, max:70 } widthRange[66] = { min:52, max:70 } widthRange[90] = { min:70, max:94 }
Enfoque declarativo:
const relevantKeys = [46,66,90] const relevantValues = Object.keys(widthRange) .filter(index => relevantKeys.includes(parseInt(index))) .map(relevantIndex => widthRange[relevantIndex])
Object.keys
para obtener las claves, usandoparseInt
para lanzarlas como números.filter
para conseguir solo los que quieras.map
para construir una matriz a partir del objeto original de solo los índices que busca, ya queObject.keys
pierde los valores del objeto.Depurar:
console.log(widthRange) console.log(relevantKeys) console.log(relevantValues)
fuente
La pregunta es bastante antigua, pero hoy en día puede usar forEach, que es eficiente y conservará las claves como números:
let keys = widthRange.map((v,k) => k).filter(i=>i!==undefined))
Esto recorre widthRange y crea una nueva matriz con el valor de las claves, y luego filtra todas las ranuras de sparce tomando solo los valores que están definidos.
(Mala idea, pero para thorughness: Si la ranura 0 siempre estaba vacío, que podría reducirse a
filter(i=>i)
ofilter(Boolean)
Y, puede ser menos eficiente, pero los números se pueden lanzar con
let keys = Object.keys(array).map(i=>i*1)
fuente