Come trovare le chiavi di un hash?


178

conosco in oggetti JavaScript doppia come hash, ma sono stato in grado di trovare un costruito in funzione per ottenere le chiavi

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

voglio qualcosa di simile

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

E 'semplice scrivere una funzione me stesso per scorrere gli elementi e aggiungere le chiavi a un array che ritorno, ma esiste un modo standard e più pulito per farlo?

Continuo a sentire che deve essere una semplice funzione incorporata che mi è sfuggita ma non riesco a trovarla!

  0

I sto saltando su javascript ma questo post potrebbe aiutarti. http://dean.edwards.name/weblog/2006/07/enum/ 20 ago. 082008-08-20 21:47:42

  0

Possibile duplicato di [Ottieni array di chiavi dell'oggetto] (http://stackoverflow.com/questions/8763125/get-array-of-objects- chiavi) 02 feb. 162016-02-02 13:48:01

+1

Che dire ottenere i valori dai tasti? Inoltre, ottenendo il numero di chiavi in ​​un hash. 10 mag. 162016-05-10 19:52:29

  0

La risposta 2017: Object.keys (h) Object.values ​​(h) 24 mag. 172017-05-24 13:29:55

249

C'è funzione in javascript moderna (ECMAScript 5) chiamato Object.keys di eseguire questa operazione:

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

dettagli di compatibilità possono essere trovati here.

Su Mozilla site c'è anche uno snipped per compatibilità all'indietro:

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

non sarebbe stato più naturale? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Object (this)) lanciare un nuovo TypeError ('Object.keys chiamato on-object'); var ret = [], p; per (p in questo) 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}}; Avviso (x.a.keys()); ' 22 dic. 112011-12-22 00:44:09

+2

Come ho capito questo' Object.prototype.keys' renderà le chiavi '' disponibili per tutte le sottoclassi di Object, quindi per tutti gli oggetti. Quale probabilmente vuoi se stai cercando di usare OOP. Ad ogni modo questo dipende molto dalle tue esigenze. 22 dic. 112011-12-22 21:12:31

+1

Se si utilizzano mootools, Object.keys() dovrebbe essere disponibile in tutti i browser. 10 set. 122012-09-10 16:43:47

  0

C'è qualcosa da usare in modelli angolari? Non funziona lì dentro i partial. 06 dic. 132013-12-06 14:52:42

  0

Penso che dovresti chiedere a questo come una domanda separata con un esempio di codice. 07 dic. 132013-12-07 01:05:41


13

Questo è il meglio che si può fare, per quanto ne so ...

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

Anche questo non funziona quando Object.prototype è stato modificato. 26 lug. 112011-07-26 08:40:14

+4

Sarebbe meglio usare questo e non "fare casino con" Object.prototype. Sembra che tutto si rompa se aggiungiamo cose a Object.prototype: è un idioma estremamente comune per eseguire il looping sulle chiavi di un array/oggetto. 07 mag. 122012-05-07 07:59:30


6

credo ciclo attraverso le proprietà dell'oggetto è possibile utilizzare per/a, così si potrebbe fare qualcosa di simile :

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

Questo non funziona, vedere la risposta di Annan 26 lug. 112011-07-26 08:39:16


79

per il codice di produzione che richiedono una grande compatibilità con i browser client ho ancora suggeriscono la risposta di Ivan Nevostruev sopra con spessore per garantire Object.keys nei browser più vecchi. Tuttavia, è possibile ottenere l'esatta funzionalità richiesta utilizzando la nuova funzione defineProperty di ECMA.

Dal ECMAScript 5 - Object.defineProperty

Come di ECMA5 è possibile utilizzare Object.defineProperty() per definire le proprietà non enumerabili. Il current compatibility ha ancora molto da desiderare, ma dovrebbe diventare utilizzabile in tutti i browser. (Si noti in particolare l'incompatibilità corrente con 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"] 

Tuttavia, poiché ECMA5 già aggiunto Object.keys si potrebbe anche usare:

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

risposta originale

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

Modifica: Dal momento che questa risposta è stata in giro per un po 'lascerò intatto quanto sopra. Chiunque legga questo dovrebbe anche leggere la risposta di Ivan Nevostruev qui sotto.

Non c'è modo di rendere le funzioni di prototipo non enumerabili che portano a esse sempre in loop for-in che non utilizzano hasOwnProperty. Penso ancora che questa risposta sarebbe l'ideale se estendere il prototipo di Object non fosse così disordinato.

+9

'hasOwnProperty' esclude le proprietà sui prototipi di questo oggetto, che è utile sapere. 13 nov. 092009-11-13 11:09:58

+2

Risposta accettata perché è così che ho finito per implementarlo ma ritengo che questa dovrebbe essere una funzione incorporata del linguaggio. 29 mar. 112011-03-29 22:16:48

+5

Nota che dovresti usare "for (var i in this) ..." per evitare di creare una variabile globale. 13 mag. 112011-05-13 12:31:03

+5

Eviterei di modificare Object.prototype - come un altro commentatore annotato di seguito, questo può facilmente interrompere gli script che non fanno attenzione al controllo di hasOwnProperty(). Invece, usa il modo meno intuitivo di OO: definisci una funzione 'chiavi' se non esiste già. (Firefox e Chrome implementano entrambe una funzione native keys() che fa esattamente quello che l'OP vuole - IE no) 31 mag. 112011-05-31 22:08:04

  0

Non c'è un 'Object.prototype.keys' in ECMAScript 5. https://gist.github.com/1034464 11 ago. 112011-08-11 18:35:49

+1

Sembra essere una cattiva idea aggiungere qualcosa a Object.prototype, poiché interrompe ogni ciclo normale come: for (var k in array) {} o for (var k in object), e quell'idioma - sebbene potrebbe essere difettoso - è estremamente comune. Ad esempio, secondo la risposta di Matthew Darwin in basso, rompe Google Maps. 07 mag. 122012-05-07 08:01:00

  0

Questa non è la strada da percorrere per una serie di motivi; 1) Non dovresti davvero aggiungere cose a 'Object.prototype' affatto, e certamente non in questo modo 2) Dovresti usare' Object.keys' come accennato nella risposta di Ivan Nevostuev 03 set. 122012-09-03 14:32:07

  0

@OliverNightingale Non so come per fare il tuo commento Ho già detto la stessa cosa nella parte * Modifica * della mia risposta. 10 set. 122012-09-10 12:15:17


4

ho voluto usare la risposta nominale superiore sopra

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

Tuttavia quando si utilizza in combinazione con l'API v3 google maps, mappe di Google non è funzionale.

for (var key in h) ... 

funziona bene.


34

Si potrebbe utilizzare Underscore.js, che è una libreria di utilità Javascript.

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

Beh, non è proprio quello che è stato chiesto, perché @Pat sta cercando una funzione built-in, ma è comunque una libreria interessante, e non modifica 'Object.prototype' 11 ago. 112011-08-11 22:11:34

+2

In questi giorni, penso che sia molto più utile usare queste piccole librerie - lascia che continuare a scrivere le proprie implementazioni ... Comunque, nella maggior parte dei progetti del mondo reale, utilizziamo comunque le librerie Underscore o equivalenti. Personalmente, preferirei andare con Underscore. 22 ago. 122012-08-22 20:40:48

  0

'_.keys (obj) .length' per vedere se ci sono delle chiavi. 24 set. 122012-09-24 21:04:50


9

utilizzando jQuery è possibile ottenere le chiavi di questo tipo ...

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

grazie alla @pimlottc

+3

Se si vuole percorrere questa strada, si potrebbe anche usare 'JQuery.map': ' $ .map (h, function (v, k) {return k;}); ' 16 mag. 122012-05-16 14:20:10


1

se si sta cercando di ottenere il solo gli elementi ma non le funzioni allora questo codice può aiutarti

this.getKeys = function() { 

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

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

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

}

questo fa parte della mia attuazione del HashMap e voglio solo le chiavi, this è l'oggetto hashmap che contiene le chiavi


38

è possibile utilizzare Object.keys

Object.keys(h) 
+3

Aggiunto in ECMAScript 5, ma dovrebbe lavoro nella maggior parte dei browser principali ormai 30 ago. 132013-08-30 10:15:00