Ich habe ein Array mit diesem Code erstellt:
var widthRange = new Array();
widthRange[46] = { min:0, max:52 };
widthRange[66] = { min:52, max:70 };
widthRange[90] = { min:70, max:94 };
Ich möchte jeden der Werte 46, 66, 90 in einer Schleife erhalten. Ich habe es versucht, for (var key in widthRange)
aber dies gibt mir eine ganze Reihe zusätzlicher Eigenschaften (ich gehe davon aus, dass es sich um Funktionen des Objekts handelt). Ich kann keine reguläre for-Schleife verwenden, da die Werte nicht sequentiell sind.
javascript
arrays
key
DisgruntledGoat
quelle
quelle
Array.prototype.forEach
. Das AufrufenObject.keys
eines Arrays ist schlecht, da Browser nicht dafür optimieren.for(var key in array)
ist schlecht, weil es den Prototyp durchquert und jeden Ziffernschlüssel, auf den es trifft, stringifiziert (das Konvertieren von Doubles in base10 ist sehr langsam).forEach
Es wurde jedoch genau zum Zweck der Iteration von Arrays mit geringer Dichte entwickelt und bietet Ihrem Code im Vergleich zu anderen Lösungen eine hervorragende LeistungAntworten:
Sie müssen die
hasOwnProperty
Funktion aufrufen , um zu überprüfen, ob die Eigenschaft tatsächlich für das Objekt selbst definiert ist (im Gegensatz zu seinem Prototyp).for (var key in widthRange) { if (key === 'length' || !widthRange.hasOwnProperty(key)) continue; var value = widthRange[key]; }
Beachten Sie, dass Sie eine separate Prüfung für benötigen
length
.Sie sollten hier jedoch überhaupt kein Array verwenden. Sie sollten ein reguläres Objekt verwenden. Alle Javascript-Objekte fungieren als assoziative Arrays.
Zum Beispiel:
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 };
quelle
length
? Ist nicht wie[[DontEnum]]
in allen Browsern markiert ?Die String-Schlüssel können mit abgefragt werden
Object.keys(array)
.quelle
array.keys()
nichts zurückgegeben wurde.Wenn Sie irgendeine Art von Manipulation oder Inspektion von Arrays / Sammlungen durchführen, empfehle ich dringend die Verwendung von Underscore.js . Es ist klein, gut getestet und erspart Ihnen Tage / Wochen / Jahre Javascript-Kopfschmerzen. Hier ist seine Tastenfunktion:
Schlüssel
Rufen Sie alle Namen der Objekteigenschaften ab.
_.keys({one : 1, two : 2, three : 3}); => ["one", "two", "three"]
quelle
Angenommen, Ihr Array sah aus wie
arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ]
(oder möglicherweise andere Schlüssel), die Sie ausführen könntenarr.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"]
quelle
for (var i = 0; i < widthRange.length; ++i) { if (widthRange[i] != null) { // do something } }
Sie können nicht wirklich nur die Schlüssel erhalten, die Sie festgelegt haben, da ein Array so nicht funktioniert. Sobald Sie Element 46 gesetzt haben, haben Sie auch 0 bis 45 gesetzt (obwohl sie null sind).Sie können immer zwei Arrays haben:
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]]); }
gut bearbeiten es kann sein, dass ich hier ganz nass bin ...
quelle
widthRange.map(function(_, i) { return i });
oder
widthRange.map((_, i) => i);
quelle
Ihr ursprüngliches Beispiel funktioniert gut für mich:
<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>
Ergebnisse im Browser (Firefox 3.6.2 unter Windows XP):
Key #1 = 46; min/max = 0/52 Key #2 = 66; min/max = 52/70 Key #3 = 90; min/max = 70/94
quelle
Ich denke, Sie sollten dafür ein Object (
{}
) und kein Array ([]
) verwenden.Jedem Schlüssel ist ein Datensatz zugeordnet. Es schreit nach einem Objekt. Tun:
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]); }
Vielleicht können solche Hilfsprogramme helfen:
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]); }
quelle
Scheint zu funktionieren.
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 />"); }
quelle
Ich habe eine Funktion geschrieben, die mit jeder Instanz von Objekten gut funktioniert (Arrays sind solche).
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; };
Verwendung:
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());
Ausgabe:
> [ 1, 2, 3, 4, 5 ] > [ 7, 1, 2, 3, function () { return 4; }, 5 ]
Es kann für jeden nützlich sein.
quelle
... ????
Alternativ, wenn Sie eine Liste von Elementen haben, die Sie verwenden möchten ...
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('')); }
quelle
Für Ihre Eingabedaten:
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 }
Deklarativer Ansatz:
const relevantKeys = [46,66,90] const relevantValues = Object.keys(widthRange) .filter(index => relevantKeys.includes(parseInt(index))) .map(relevantIndex => widthRange[relevantIndex])
Object.keys
um die Schlüssel zu erhalten, verwenden SieparseInt
sie als Zahlen.filter
um nur diejenigen zu bekommen, die Sie wollen.map
um ein Array aus dem ursprünglichen Objekt nur der Indizes zu erstellen, nach denen Sie suchen, daObject.keys
die Objektwerte verloren gehen.Debuggen:
console.log(widthRange) console.log(relevantKeys) console.log(relevantValues)
quelle
Die Frage ist ziemlich alt, aber heutzutage können Sie forEach verwenden, was effizient ist und die Schlüssel als Zahlen behält:
let keys = widthRange.map((v,k) => k).filter(i=>i!==undefined))
Dies durchläuft widthRange und erstellt ein neues Array mit dem Wert der Schlüssel. Anschließend werden alle Sparce-Slots herausgefiltert, indem nur die definierten Werte verwendet werden.
(Schlechte Idee, aber aus Gründen der Gründlichkeit: Wenn Steckplatz 0 immer leer war, könnte dies auf
filter(i=>i)
oder verkürzt werdenfilter(Boolean)
Und es mag weniger effizient sein, aber die Zahlen können mit gegossen werden
let keys = Object.keys(array).map(i=>i*1)
quelle