Comment trouver les clés d'un hachage?


178

Je sais en javascript les objets doubles comme hash mais je n'ai pas été en mesure de trouver une fonction intégrée pour obtenir les clés

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

Je veux quelque chose comme

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

Il est simple d'écrire une fonction moi-même pour itérer sur les éléments et ajouter les clés à un tableau que je reviens, mais y at-il une façon plus propre de faire cela?

Je continue à sentir que ça doit être une simple fonction intégrée que j'ai manquée mais que je ne trouve pas!

  0

I Je suis juste en train de sauter dans javascript mais ce message peut vous aider. http://dean.edwards.name/weblog/2006/07/enum/ 20 août. 082008-08-20 21:47:42

  0

Copie possible de [Obtenir le tableau des clés de l'objet] (http://stackoverflow.com/questions/8763125/get-array-of-objects- keys) 02 févr.. 162016-02-02 13:48:01

+1

Qu'en est-il de l'obtention des valeurs à partir des clés? En outre, obtenir le nombre de clés dans un hachage. 10 mai. 162016-05-10 19:52:29

  0

La réponse de 2017: Object.keys (h) Object.values ​​(h) 24 mai. 172017-05-24 13:29:55

249

Il est fonction javascript moderne (ECMAScript 5) appelé Object.keys effectuer cette opération:

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

détails de compatibilité peuvent être trouvés here.

Sur Mozilla site il y a aussi une Snipped pour la compatibilité descendante:

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

cela n'aurait-il pas été plus naturel? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Objet (this)) throw nouveau TypeError ('Object.keys appelé sur non-object'); var ret = [], p; pour (p dans this) if (Object.prototype.hasOwnProperty.call (this, p)) ret.push (p); return ret; } var x = {a: {A: 1, B: 2, C: 3}, b: {A: 10, B: 20}}; alert (x.a.keys()); ' 22 déc.. 112011-12-22 00:44:09

+2

Si je comprends bien,' Object.prototype.keys' rendra 'keys' disponible pour toutes les sous-classes d'Object, donc pour tous les objets. Ce que vous voulez probablement si vous essayez d'utiliser OOP. Quoi qu'il en soit, cela dépend vraiment de vos besoins. 22 déc.. 112011-12-22 21:12:31

+1

Si vous utilisez mootools, Object.keys() devrait être disponible dans tous les navigateurs. 10 sept.. 122012-09-10 16:43:47

  0

Y a-t-il quelque chose à utiliser dans les gabarits angulaires? Cela ne fonctionne pas à l'intérieur des partiels. 06 déc.. 132013-12-06 14:52:42

  0

Je pense que vous devriez poser cette question en tant que question séparée avec l'échantillon de code. 07 déc.. 132013-12-07 01:05:41


13

C'est le meilleur que vous pouvez faire, pour autant que je sache ...

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

Cela ne fonctionne pas non plus lorsque Object.prototype a été modifié. 26 juil.. 112011-07-26 08:40:14

+4

Il serait préférable de l'utiliser, et de ne pas "gâcher" Object.prototype. Il semble que tout se casse si nous ajoutons des choses à Object.prototype: c'est un idiome extrêmement commun de faire une boucle sur les clés d'un tableau/objet. 07 mai. 122012-05-07 07:59:30


6

Je crois que vous pouvez parcourir les propriétés de l'objet en utilisant pour /, donc vous pourriez faire quelque chose comme ça :

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

Cela ne fonctionne pas, voir la réponse de Annan 26 juil.. 112011-07-26 08:39:16


79

pour le code de production nécessitant une grande compatibilité avec les navigateurs client je suggère toujours la réponse d'Ivan Nevostruev ci-dessus avec cale pour assurer Object.keys dans les anciens navigateurs. Cependant, il est possible d'obtenir la fonctionnalité exacte demandée en utilisant la nouvelle fonctionnalité defineProperty d'ECMA.

Au ECMAScript 5 - Object.defineProperty

Au ECMA5 vous pouvez utiliser Object.defineProperty() pour définir les propriétés non-dénombrables. Le current compatibility a encore beaucoup à désirer, mais cela devrait éventuellement devenir utilisable dans tous les navigateurs. (Note précisément l'incompatibilité actuelle avec 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"] 

Cependant, depuis ECMA5 déjà ajouté Object.keys vous pourriez aussi bien utiliser:

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

réponse originale

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

Modifier: Depuis cette réponse a été autour depuis un certain temps, je vais laisser ce qui précède intacte. Toute personne lisant ceci devrait également lire la réponse d'Ivan Nevostruev ci-dessous.

Il n'y a aucun moyen de rendre les fonctions prototypes non énumérables, ce qui les amène toujours à apparaître dans les boucles for-in qui n'utilisent pas hasOwnProperty. Je pense toujours que cette réponse serait idéale si étendre le prototype d'Object n'était pas si compliqué.

+9

'hasOwnProperty' exclut les propriétés sur les prototypes de cet objet, ce qui est utile à savoir. 13 nov.. 092009-11-13 11:09:58

+2

Réponse acceptée parce que c'est ainsi que j'ai fini par l'implémenter mais je pense que cela aurait dû être une fonction intégrée de la langue. 29 mars. 112011-03-29 22:16:48

+5

Notez que vous devez utiliser "for (var i in this) ..." pour éviter de créer une variable globale. 13 mai. 112011-05-13 12:31:03

+5

J'éviterais de modifier Object.prototype - comme un autre commentateur noté ci-dessous, cela peut facilement casser des scripts qui ne font pas attention à vérifier hasOwnProperty(). Au lieu de cela, utilisez la méthode moins OO-friendly: définissez une fonction 'keys' si elle n'existe pas déjà. (Firefox et Chrome implémentent tous deux une fonction native keys() qui fait exactement ce que l'OP veut - IE ne le fait pas) 31 mai. 112011-05-31 22:08:04

  0

Il n'y a pas de 'Object.prototype.keys' dans ECMAScript 5. https://gist.github.com/1034464 11 août. 112011-08-11 18:35:49

+1

Il semble que ce soit une mauvaise idée d'ajouter quoi que ce soit à Object.prototype, car il casse toute boucle normale comme: for (var k dans array) {} ou for (var k dans object), et cet idiome - bien qu'il peut être défectueux - est extrêmement commun. Par exemple, selon la réponse de Matthew Darwin ci-dessous, il casse Google Maps. 07 mai. 122012-05-07 08:01:00

  0

Ce n'est pas la voie à suivre pour un certain nombre de raisons; 1) Vous ne devriez vraiment pas ajouter des choses à 'Object.prototype' du tout, et certainement pas de cette façon 2) Vous devriez utiliser' Object.keys' comme mentionné dans la réponse d'Ivan Nevostuev 03 sept.. 122012-09-03 14:32:07

  0

@OliverNightingale Je ne sais pas comment pour prendre votre commentaire. Je dis déjà la même chose dans la partie * Edit * de ma réponse. 10 sept.. 122012-09-10 12:15:17


4

Je voulais utiliser la réponse ci-dessus les mieux notés

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

Cependant lors de l'utilisation en conjonction avec l'API Google Maps v3, Google Maps est non fonctionnel.

for (var key in h) ... 

fonctionne bien.


34

Vous pouvez utiliser Underscore.js, qui est une bibliothèque utilitaire Javascript.

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

Eh bien, ce n'est pas vraiment ce qui a été demandé, parce que @Pat recherche une fonction intégrée, mais c'est néanmoins une bibliothèque intéressante, et elle ne modifie pas 'Object.prototype' 11 août. 112011-08-11 22:11:34

+2

Ces jours-ci, je pense que c'est beaucoup plus utile Pour utiliser ces astucieuses petites librairies plutôt que d'écrire vos propres implémentations ... De toute façon, dans la plupart des projets du monde réel, nous utilisons de toute façon Underscore ou des bibliothèques équivalentes. Personnellement, je préfère aller avec Underscore. 22 août. 122012-08-22 20:40:48

  0

'_.keys (obj) .length' pour voir s'il y a des clés. 24 sept.. 122012-09-24 21:04:50


9

utilisant jquery vous pouvez obtenir les clés comme celui-ci ...

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

Ou -

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

grâce à @pimlottc

+3

Si vous voulez suivre cette route, vous pouvez aussi bien utiliser 'JQuery.map': ' $ .map (h, fonction (v, k) {return k;}); ' 16 mai. 122012-05-16 14:20:10


1

si vous essayez d'obtenir la éléments seulement mais pas les fonctions alors ce code peut vous aider

this.getKeys = function() { 

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

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

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

}

cela fait partie de ma mise en œuvre du HashMap et je veux que les clés, this est l'objet hashmap qui contient les clés


38

vous pouvez utiliser Object.keys

Object.keys(h) 
+3

Ajouté dans ECMAScript 5 mais devrait travailler dans la plupart des navigateurs principaux maintenant 30 août. 132013-08-30 10:15:00