2010-03-24 3 views
65

Ich habe ein Array mit diesem Code erstellt:Wie erhalten Sie Array-Schlüssel in Javascript?

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 46 jeden der Werte bekommen, 66, 90 in einer Schleife. Ich habe versucht for (var key in widthRange), aber das gibt mir eine ganze Reihe von zusätzlichen Eigenschaften (ich nehme an, dass sie Funktionen auf dem Objekt sind). Ich kann keine reguläre for-Schleife verwenden, da die Werte nicht sequentiell sind.

+8

Es sieht aus wie Sie Daten haben, die, obwohl es zufällige numerische Tasten hat, nicht tatsächlich Array-Daten sind. Ich würde mir hier ein normales Objekt ansehen. – Quentin

Antwort

87

Sie müssen die hasOwnProperty Funktion aufzurufen Überprüfen Sie, ob die Eigenschaft tatsächlich auf dem Objekt selbst (im Gegensatz zu seinem Prototyp) definiert ist:

for (var key in widthRange) { 
    if (key === 'length' || !widthRange.hasOwnProperty(key)) continue; 
    var value = widthRange[key]; 
} 

Beachten Sie, dass Sie eine separate Überprüfung für length benötigen.
Allerdings sollten Sie hier überhaupt kein Array verwenden; Sie sollten ein normales Objekt verwenden. Alle Javascript-Objekte funktionieren 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 }; 
+2

Wirklich? Wow ich lerne hier jeden Tag etwas, und so oft kommt es von dir SLaks :-) Ich bin überrascht, dass Array seine explizit gesetzten Indizes so verfolgt. Vielleicht sollte ich nicht sein. – Pointy

+0

@SLaks: Danke, es zu einem Objekt zu ändern scheint die beste Lösung zu sein. Noch eine Frage: Gibt es eine Möglichkeit, in umgekehrter Reihenfolge zu iterieren? – DisgruntledGoat

+0

Nein; Sie müssen es selbst tun. – SLaks

3
for (var i = 0; i < widthRange.length; ++i) { 
    if (widthRange[i] != null) { 
    // do something 
    } 
} 

Sie können wirklich nicht bekommen nur die Tasten, die Sie festgelegt haben, weil das nicht ist, wie ein Array funktioniert. Sobald Sie Element 46 gesetzt haben, haben Sie auch 0 bis 45 gesetzt (obwohl sie null sind).

könnten Sie haben immer zwei Arrays:

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]]); 
} 

bearbeiten gut kann es sein, dass ich ganz nass hier bin ...

+0

Arrays verfolgen nur die Länge, sie gehen nicht durch und erzeugen so viele Objekte. Wenn ein neuer Index gefunden wird, prüft er, ob dieser neue Index größer als die Länge ist ... wenn der neue Index die neue Länge erhält. Aus diesem Grund ist es möglich, nur die Indizes zu erhalten, die Sie mit einer For-In-Schleife definiert haben. – Bob

1

Ihr ursprüngliches Beispiel funktioniert für mich ganz gut:

<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 + "; &nbsp;&nbsp;&nbsp; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />"); 
    i++; 
} 
</script> 
</html> 

Ergebnisse im Browser (Firefox 3.6.2 auf Windows XP):

Key #1 = 46;  min/max = 0/52 
Key #2 = 66;  min/max = 52/70 
Key #3 = 90;  min/max = 70/94 
+2

Ich wette, er importiert Prototype oder so ähnlich. Im Allgemeinen sind diese "in" -Schleifen riskant. – Pointy

+0

Nun, ich benutze jQuery, aber auch Joomla, die mootools verwendet, etwas fügt diese Eigenschaften hinzu. – DisgruntledGoat

0

Scheint zu arbeiten.

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 />"); 
} 
1

Ich glaube, Sie ein Objekt verwenden soll ({}) und kein Array ([]) dafür.

Jedem Schlüssel ist ein Datensatz zugeordnet. Es schreit nach einem Objekt. Sie:

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 ein Dienstprogramm Sachen wie diese helfen können:

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]); 
} 
18

Wenn Sie jede Art von Array/Sammlung Manipulation oder Inspektion tun Ich empfehle Underscore.js verwenden. Es ist klein, gut getestet und wird Ihnen Tage/Wochen/Jahre Javascript Kopfschmerzen ersparen. Hier ist die Tasten-Funktion:

Keys

Rufen Sie alle Namen der Eigenschaften des Objekts.

_.keys({one : 1, two : 2, three : 3}); 
=> ["one", "two", "three"] 
0

Ich schrieb eine Funktion, was mit jeder Instanz von Gegenständen funktioniert gut (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; 
}; 

Verbrauch:

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()); 

Ausgang:

> [ 1, 2, 3, 4, 5 ] 
> [ 7, 1, 2, 3, function() { return 4; }, 5 ] 

Es kann für jedermann nützlich sein.

+2

Das Erweitern eines Prototyps, den Sie nicht erstellt haben, ist eine sehr schlechte Idee, egal wie bequem Sie denken, dass es ist. – doug65536

54

Die beschrifteten Schlüssel können mit Object.keys(array) abgefragt werden.

+2

danke, genau was ich brauchte. – spazm

+0

Dies gibt die Schlüssel als Zeichenfolgen zurück, nicht als Zahlen, nur damit jeder davon weiß. –

0

... ????

Alternativ, wenn Sie eine Liste der Artikel, 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('')); 

    } 
2

Sagen Sie Ihre 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 Tasten) Sie tun könnten

arr.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"]

2
widthRange.map(function(_, i) { return i }); 

oder

widthRange.map((_, i) => i);