2016-02-05 14 views
5

Esiste un determinato oggetto in cui il caso esatto delle proprietà non è noto in anticipo. Ad esempio, un nome di proprietà potrebbe essere "AbC" o "Abc" o "abc", ecc.Esiste un modo efficace per eseguire una ricerca del nome della proprietà dell'oggetto JavaScript senza distinzione tra maiuscole e minuscole?

Tuttavia, so che esiste solo uno. Cioè so che non ci può essere sia una proprietà "AbC" e anche una proprietà "abc".

Il nome della proprietà è sensibile al maiuscolo/minuscolo. Quindi se è archiviato come theObject.Abc e cerco theObject.abc non troverò la proprietà.

Nel mio oggetto potrebbero esserci 1000 proprietà di questo tipo.

Sarebbe, possibile, ma inefficiente, se ogni volta che volevo fare una ricerca ho confrontato il valore minuscolo della proprietà che voglio trovare contro il valore minuscolo dei nomi di proprietà, come questo:

propertyName = inputValue.toLowerCase(); 
for (var i in theObject) { 
    if (propertyName == i.toLowerCase()); // found a matching property name 
} 

Qualcuno conosce un modo più intelligente per farlo?

Per ragioni che richiederebbero troppo tempo per spiegare, non posso semplicemente ricreare l'oggetto e rendere tutte le proprietà minuscole. Mi rendo conto che se fosse possibile, potrei semplicemente trovare

theObject['inputValue'.toLowerCase()] 

direttamente. Ma come ho detto, non posso. I nomi delle proprietà in theObject sono ciò che sono e non possono essere modificati. Chiedendomi perché sarebbe una grande digressione dal problema in questione. Per favore prendi la mia parola per questo che theObject è bloccato con i nomi delle proprietà che ha.

Qualcuno conosce un modo efficiente di eseguire una ricerca del nome di proprietà senza distinzione tra maiuscole e minuscole in una situazione come questa?

+0

Si potrebbe probabilmente ottimizza l'istruzione if confrontando prima la lunghezza delle stringhe. Puoi anche memorizzare una mappa in cache se non cambiano. A parte questo, non la penso così. –

+0

'propertyName = inputValue.toLowerCase(); if (Object.keys (theObject).map (function (v) {return v.toLowerCase();}). indexOf (propertyName)> - 1) {// .....} ' –

+0

Questo usa regex e scorre attraverso le chiavi. http://stackoverflow.com/a/6223307/548568 – blessenm

risposta

3

Come dici tu, non penso che tu voglia il ciclo del modo Oggetto. E per te l'opinione, ho pensato in un modo, che è più efficace e facile, e non loop nulla.

vediamo il violino:

https://fiddle.jshell.net/skgkLnx9/

qui è l'esempio:

var theObject = {aBc: 1, BBA: 2, CCCa: 4, Dba: 3}; 
// if your env is < ES5, you can use a polyfill(like underscore or lodash provided `_.keys` method) 
var theKeys = Object.getOwnPropertyNames(theObject).toString(); 
// or var theKeys = Object.keys(theObject); 

var getPropValue = function(prop){ 
    var match = new RegExp(prop, 'i').exec(theKeys); 
    return match && match.length > 0 ? theObject[match[0]] : ''; 
} 

console.log(getPropValue('abc')) 

console.log(getPropValue('Dba')) 

Ho anche ottenere la vostra considerazione circa i dati di grandi dimensioni si have.I anche utilizzare il mio codice per testare un oggetto che ha 500 proprietà è in grado di restituire direttamente. Anche se è molto grande, può avere qualche problema di memoria, penso che questo possa darti un'idea della risoluzione di t.

desiderio potrebbe aiutare :)

+0

Che sicuramente sembra interessante! Mi chiedo perché ottengo un errore 'Object.getOwnPropertyNames non è una funzione 'quando lo provo sul mio server. Riferirò di nuovo dopo ulteriori indagini! Grazie. –

+0

Questo può avere due possibilità. Uno è il tuo javascript env è Jelly

3

Partendo ad esempio di gelatina, ma forse più efficiente o più facile da capire:

var theObject = {aBc: 1, BBA: 2, CCCa: 4, Dba: 3}; 
var theKeys = Object.getOwnPropertyNames(theObject); 
var lookup = {}; 
theKeys.forEach(function(key) { 
    lookup[key.toLowerCase()] = key; 
}); 

var getPropValue = function(prop){ 
    return lookup[prop.toLowerCase()]; 
} 
console.log(getPropValue('abc')) 
console.log(getPropValue('Dba')) 
3

E andando anche oltre Sigfried:

var theObject = {aBc: 1, BBA: 2, CCCa: 4, Dba: 3}; 

var lcKeys = Object.keys (theObject).reduce (
          function (keys, k) { keys[k.toLowerCase()] = k; 
               return keys }, {}); 

function getValue (key) { return theObject[lcKeys[key.toLowerCase()]] } 

console.log (getValue ('abc')); 
console.log (getValue ('Dba')); 
+1

Come è migliorativo il mio? (Questa è una domanda genuina, non mi sto difendendo, sembra un po 'meno facile da capire, ma se acquisti qualcosa per quello, ne vale la pena, ma non posso dire cosa stai comprando.) – Sigfried

+0

potrebbe essere solo una preferenza personale, ma dichiaro una variabile solo quando sono richiesti più riferimenti ("theKeys" nel tuo codice viene fatto riferimento una sola volta). Mi sono abituato a usare Object.keys, restituisce solo le chiavi enumerabili, il tuo codice includerà chiavi non enumerabili (il che non è probabile che sia un problema ma probabilmente dovrebbe essere menzionato). Il metodo 'reduce' rende anche più chiaro (per me!) Che stiamo generando un oggetto. – HBP

+0

Grazie per l'elaborazione. Lo apprezzo. Vorrei che il mio cervello elaborato si riducesse più velocemente. Non riesco a leggerli senza muovere le labbra. :) – Sigfried

Problemi correlati