Wie finden Sie Schlüssel eines Hash?


178

ich in Javascript wissen Objekte doppelt so Hashes, aber ich habe es nicht gelungen, eine integrierte Funktion zu finden, die Schlüssel

var h = {a:'b',c:'d'}; 

Ich möchte so etwas wie

var k = h.keys() ; // k = ['a','c']; 

Es ist einfach zu bekommen, eine Funktion zu schreiben ich selbst, um über die Elemente zu iterieren und die Schlüssel zu einem Array, das ich zurückgeben, hinzufügen, aber gibt es einen Standard sauberer Weg, das zu tun?

Ich habe das Gefühl, es muss eine einfache eingebaute Funktion sein, die ich vermisst habe, aber ich kann sie nicht finden!

  0

ich verwenden kann, bin gerade in Javascript springen, aber dieser Beitrag kann Ihnen helfen. http://dean.edwards.name/weblog/2006/07/enum/ 20 aug. 082008-08-20 21:47:42

  0

Mögliches Duplikat von [Get Array von Objektschlüsseln] (http://stackoverflow.com/questions/8763125/get-array-of-objects-) Schlüssel) 02 feb. 162016-02-02 13:48:01

+1

Was ist mit den Werten von den Schlüsseln? Außerdem wird die Anzahl der Schlüssel in einem Hashwert ermittelt. 10 mai. 162016-05-10 19:52:29

  0

Die Antwort von 2017: Object.keys (h) Object.values ​​(h) 24 mai. 172017-05-24 13:29:55

249

Es gibt Funktion in der modernen Javascript (ECMAScript 5) genannt Object.keys Durchführung dieser Operation:

var obj = { "a" : 1, "b" : 2, "c" : 3}; 
alert(Object.keys(obj)); // will output ["a", "b", "c"] 

Kompatibilität Details here gefunden werden kann.

Auf Mozilla site gibt es auch eine snipped für die Abwärtskompatibilität:

if(!Object.keys) Object.keys = function(o){ 
    if (o !== Object(o)) 
     throw new TypeError('Object.keys called on non-object'); 
    var ret=[],p; 
    for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p); 
    return ret; 
} 
  0

wäre das nicht natürlicher? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Objekt (this)) throw new TypeError ('Object.keys bei Nicht-Objekt aufgerufen'); varret = [], p; für (p in diesem) if (Object.prototype.hasOwnProperty.call (this, p)) ret.push (p); Rückkehr ret; } var x = {a: {A: 1, B: 2, C: 3}, b: {A: 10, B: 20}}; alert (x.a.keys()); ' 22 dez. 112011-12-22 00:44:09

+2

Nach meinem Verständnis wird' Object.prototype.keys' alle Schlüsselklassen von Object für alle Objekte verfügbar machen. Was Sie wahrscheinlich wollen, wenn Sie versuchen, OOP zu verwenden. Wie auch immer, das hängt wirklich von Ihren Anforderungen ab. 22 dez. 112011-12-22 21:12:31

+1

Wenn Sie mootools verwenden, sollte Object.keys() in allen Browsern verfügbar sein. 10 sep. 122012-09-10 16:43:47

  0

Gibt es etwas, um dies in eckigen Vorlagen zu verwenden? Es funktioniert nicht innerhalb von Teiltönen. 06 dez. 132013-12-06 14:52:42

  0

Ich denke, Sie sollten dies als separate Frage mit Codebeispiel fragen. 07 dez. 132013-12-07 01:05:41


13

Dies ist das Beste, was Sie tun können, soweit ich weiß ...

var keys = []; 
for (var k in h)keys.push(k); 
+2

Dies funktioniert auch nicht, wenn Object.prototype durcheinander gebracht wurde. 26 jul. 112011-07-26 08:40:14

+4

Es wäre besser, dies zu verwenden und nicht mit dem Objekt "Object.prototype" zu verfahren. Es scheint, dass alles bricht, wenn wir Object.prototype Dinge hinzufügen: Es ist ein sehr gebräuchliches Idiom, um die Schlüssel eines Arrays/Objekts zu durchlaufen. 07 mai. 122012-05-07 07:59:30


6

Ich glaube, Sie Schleife durch die Eigenschaften des Objekts in für/mit, so dass Sie so etwas tun könnte :

function getKeys(h) { 
    Array keys = new Array(); 
    for (var key in h) 
    keys.push(key); 
    return keys; 
} 
  0

Dies funktioniert nicht, siehe Annans Antwort 26 jul. 112011-07-26 08:39:16


79

Für Code Produktion eine große Kompatibilität mit Client-Browser erforderlich ich schlage vor, noch Ivan Nevostruev Antwort oben mit Shim Object.keys in älteren Browsern zu gewährleisten. Es ist jedoch möglich, die genaue Funktionalität zu erhalten, die mit der neuen Funktion defineProperty von ECMA angefordert wird.

Ab ECMAScript 5 - Object.defineProperty

Ab ECMA5 Sie Object.defineProperty() zu definieren, nicht-zählbare Eigenschaften verwenden können. Die current compatibility hat immer noch viel zu wünschen übrig, aber das sollte schließlich in allen Browsern nutzbar sein. (Beachten Sie Insbesondere die aktuelle Inkompatibilität mit IE8!)

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) { 
     keys.push(i); 
    } 
    return keys; 
    }, 
    enumerable: false 
}); 

var o = { 
    'a': 1, 
    'b': 2 
} 

for (var k in o) { 
    console.log(k, o[k]) 
} 

console.log(o.keys()) 

# OUTPUT 
# > a 1 
# > b 2 
# > ["a", "b"] 

Da jedoch ECMA5 bereits Object.keys hinzugefügt Sie könnte genauso gut verwenden:

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    return Object.keys(this); 
    }, 
    enumerable: false 
}); 

Ursprüngliche Antwort

Object.prototype.keys = function() 
{ 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) 
    { 
    keys.push(i); 
    } 
    return keys; 
} 

Bearbeiten: Da diese Antwort schon seit einiger Zeit existiert, werde ich das oben Gesagte unberührt lassen. Jeder, der dies liest, sollte auch die folgende Antwort von Ivan Nevostruev lesen.

Es gibt keine Möglichkeit, Prototypfunktionen nicht aufzählbar zu machen, was dazu führt, dass sie immer in For-In-Schleifen auftauchen, die nicht hasOwnProperty verwenden. Ich denke immer noch, dass diese Antwort ideal wäre, wenn die Erweiterung des Prototyps von Object nicht so unordentlich wäre.

+9

'hasOwnProperty' schließt Eigenschaften auf den Prototypen dieses Objekts aus, was nützlich ist, um zu wissen. 13 nov. 092009-11-13 11:09:58

+2

Antwort akzeptiert, weil ich es am Ende implementiert habe, aber ich denke, das sollte eine eingebaute Funktion der Sprache sein. 29 mär. 112011-03-29 22:16:48

+5

Beachten Sie, dass Sie "for (var i in this) ..." verwenden sollten, um die Erstellung einer globalen Variablen zu vermeiden. 13 mai. 112011-05-13 12:31:03

+5

Ich würde vermeiden, Object.prototype zu ändern - wie ein anderer Kommentator unten bemerkt, kann dies leicht Skripte zu brechen, die nicht sorgfältig auf hasOwnProperty() überprüfen. Verwenden Sie stattdessen die weniger OO-freundliche Methode: Definieren Sie eine Schlüsselfunktion, wenn sie nicht bereits existiert. (Firefox und Chrome implementieren beide eine native keys() -Funktion, die genau das tut, was das OP will - IE nicht) 31 mai. 112011-05-31 22:08:04

  0

Es gibt kein 'Object.prototype.keys' in ECMAScript 5. https://gist.github.com/1034464 11 aug. 112011-08-11 18:35:49

+1

Es scheint eine schlechte Idee zu sein, etwas zu Object.prototype hinzuzufügen, da es jede normale Schleife wie folgt unterbricht: für (var k im Array) {} oder für (var k im Objekt) und dieses Idiom - obwohl es könnte fehlerhaft sein - ist sehr häufig. Zum Beispiel, nach Matthew Darwins Antwort unten, bricht Google Maps. 07 mai. 122012-05-07 08:01:00

  0

Dies ist nicht der Weg aus einer Reihe von Gründen; 1) Du solltest wirklich keine Dinge zu "Object.prototype" hinzufügen, und schon gar nicht so 2) Du solltest 'Object.keys' verwenden, wie in Ivan Nevostuevs Antwort erwähnt 03 sep. 122012-09-03 14:32:07

  0

@OliverNightingale Ich bin mir nicht sicher wie um deinen Kommentar zu nehmen. Das gleiche sage ich bereits im * Edit * Teil meiner Antwort. 10 sep. 122012-09-10 12:15:17


4

ich die am besten bewertete Antwort oben

Object.prototype.keys = function() ... 

jedoch bei der Verwendung in Verbindung mit dem Google Maps API v3, Google Maps funktioniert nicht, verwenden wollte.

for (var key in h) ... 

funktioniert gut.


34

Sie Underscore.js verwenden können, das eine Javascript-Utility-Bibliothek ist.

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

Nun, es ist nicht wirklich, was gefragt wurde, denn @Pat sucht nach einer eingebauten Funktion, aber es ist dennoch eine interessante Bibliothek, und es ändert nicht 'Object.prototype' 11 aug. 112011-08-11 22:11:34

+2

In diesen Tagen denke ich, dass es viel hilfreicher ist um diese raffinierten kleinen Bibliothekslets zu benutzen, als weiter eigene Implementierungen zu schreiben ... Wie auch immer, in den meisten realen Projekten verwenden wir sowieso Underscore oder gleichwertige Bibliotheken. Persönlich würde ich lieber mit Underscore gehen. 22 aug. 122012-08-22 20:40:48

  0

'_.keys (obj) .length' um zu sehen, ob es irgendwelche Schlüssel gibt. 24 sep. 122012-09-24 21:04:50


9

mit Jquery Sie die Tasten wie diese bekommen kann ...

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
var keys = []; 
$.each(bobject, function(key,val){ keys.push(key); }); 
console.log(keys); // ["primary", "bg", "hilite"] 

Or -

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
$.map(bobject, function(v,k){return k;}); 

dank

+3

Wenn Sie diese Route gehen möchten, können Sie auch 'JQuery.map' verwenden: ' $ .map (h, Funktion (v, k) {return k;}); ' 16 mai. 122012-05-16 14:20:10


1

@pimlottc, wenn Sie das versuchen, zu erhalten Elemente nur, aber nicht die Funktionen dann kann dieser Code Ihnen helfen

this.getKeys = function() { 

var keys = new Array(); 
for(var key in this) { 

    if(typeof this[key] !== 'function') { 

     keys.push(key); 
    } 
} 
return keys; 

}

dieser Teil meiner Umsetzung der HashMap ist, und ich möchte nur die Schlüssel, ist this die hashmap Objekt, das die Tasten


38

enthält Sie Object.keys

Object.keys(h) 
+3

Hinzugefügt in ECMAScript 5 aber sollte Arbeitet in den meisten gängigen Browsern 30 aug. 132013-08-30 10:15:00