2011-07-19 25 views
9

Ho un oggetto con chiavi denominate:Come si ottengono le chiavi oggetto secondo uno schema?

var names = { 
    "Peter Pan": {...}, 
    "Peter Parker": {...}, 
    "Tony Stark": {...}, 
    ... 
} 

c'è un modo per ottenere tutte le chiavi da un modello ad es. tutte le chiavi hanno Peter in esso?

il caso è che voglio avere tutte le chiavi filtrati in un esempio matrice:

var filteredNames: [ 
    "Peter Pan", 
    "Peter Parker", 
    ... 
] 

risposta

13

Si può facilmente farlo loop delle chiavi da soli:

var filtered_keys = function(obj, filter) { 
    var key, keys = []; 
    for (key in obj) { 
    if (obj.hasOwnProperty(key) && filter.test(key)) { 
     keys.push(key); 
    } 
    } 
    return keys; 
} 
// example: 
var filteredNames = filtered_keys(names, /Peter/); // second parameter is a javascript regex object, so for exemple for case insensitive you would do /Peter/i 
+4

+1 per usare * hasOwnProperty *. Se è richiesta una corrispondenza esatta di testo normale, non è necessaria un'espressione regolare (la stringa verrà convertita in un RegExp per * corrispondenza *). Se si usa un'epsressione regolare, * test * è più adatto in quanto è un algoritmo più semplice e restituisce un valore booleano (ad esempio 'filter.test (chiave)'), mentre * match * restituisce un array che sarà convertito in tipo booleano. – RobG

3

Se lo vuoi maiuscole e minuscole:

var filteredNames = []; 

for(name in names) { 
    if(name.indexOf("Peter") > -1) { 
     filteredNames.push(name); 
    } 
} 

In caso contrario:

var filteredNames = []; 

for(name in names) { 
    if(/peter/gi.test(name)) { 
     filteredNames.push(name); 
    } 
} 
+1

Avrete anche bisogno di usare hasOwnProperty() in for in, altrimenti potreste avere chiavi selezionate da più in alto nella catena del prototipo (a meno che non sia quello che volete, ovviamente). – Lepidosteus

+0

@Lepidosteus: Tranne che è un oggetto letterale, quindi non ci saranno proprietà enumerabili sulla catena a meno che non si estenda 'Object.prototype', nel qual caso il proprio codice * dovrebbe essere interrotto * in modo da poter correggere tale difetto. – user113716

+0

Hai perfettamente ragione, ma stavo pensando più a lungo sul fatto che il suo codice fosse un esempio mentre il suo vero caso d'uso poteva essere qualcosa in cui i nomi hanno proprietà di prototipo. Avendo visto così tanti usi impropri del codice di produzione, tendo ad ottenere lo scudo prima di essere colpito, per così dire. – Lepidosteus

1

È possibile estendere il prototipo di array JavaScript, in questo modo:

Array.prototype.regex_search = function(pattern) { 
    var returns = []; 
    for(var i = 0; i < this.length; i++) { 
    if(this[i].match(pattern) { 
     returns.push(i); 
    } 
    } 
    if(returns.length) { 
    return returns; 
    } else { 
    return false; 
    } 
} 

Ora non ho ancora testato questo codice ma questo darebbe a tutti gli array che create in JavaScript un metodo .regex_search che accetta un argomento 'pattern'. Ciò restituirà false quando non vengono trovate corrispondenze o una matrice di indici quando gli elementi corrispondono.

È quindi possibile eseguire iterazioni su questo array e prelevare tali indici dall'array originale.

+0

Sta iterando sulle chiavi di un oggetto, non su un array. Inoltre, non consiglierei di modificare la catena di prototipi di oggetti nativi come Array. – Lepidosteus

+0

Hai ragione, devo averlo letto :-) – ikanobori

7
var filteredNames = Object.keys(names).filter((name) => /Peter/.test(name)); 
+1

Se questo codice è in esecuzione in un browser, tenere presente che 'forEach' e' filter' non sono supportati in IE8 e versioni precedenti. – user113716

0

ECMAscript 5.1 fornisce Object.keys() di restituire i nomi delle proprietà di un oggetto.

var obj = { 0: 'a', 1: 'b', 2: 'c' }; 
console.log(Object.keys(obj)); // console: ['0', '1', '2'] 

Source.

Standard.

Problemi correlati