Is there an efficient way to do a case-insensitive JavaScript object property name lookup?

10,681

Solution 1

And going even further than 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'));

Solution 2

Building off Jelly's example, but maybe more efficient or easier to understand:

 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'))

Solution 3

As you say, I don't think you want to the loop the Object way.And for you opinion,I thought a way, that's more effective and easy, and it don't loop anything.

let's see the fiddle:

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

here is the example:

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'))

I also get your consider about the large data you have.I also use my code to test a Object that have 500 property it's can directly return.Although when it very very large, it possible have some memory issue, I think this can give you an idea about resolve that.

wish could help you :)

Share:
10,681

Related videos on Youtube

Doug Lerner
Author by

Doug Lerner

Updated on June 04, 2022

Comments

  • Doug Lerner
    Doug Lerner almost 2 years

    There is a certain object I have where the exact case of the properties is not known ahead of time. For example, a property name might be "AbC" or "Abc" or "abc", etc.

    I do, however, know that only one exists. That is I know there can't be both a property "AbC" and also a property "abc".

    The property name itself is case-sensitive. So if it is stored as theObject.Abc and I lookup theObject.abc I won't find the property.

    In my object there might be 1,000 such properties.

    It would be, possible, but inefficient, if each time I wanted to do a lookup I compared the lower-case value of the property I want to find against the lower-case value of the property names, like this:

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

    Does anybody know a cleverer way of doing this?

    For reasons it would take too long to explain, I cannot just recreate the object and make all the properties lower-case. I do realize if that was possible I could just find

    theObject['inputValue'.toLowerCase()]
    

    directly. But as I said, I can't. The property names in theObject are what they are and they can't be changed. Asking me why would be a huge digression from the problem at hand. Please take my word for it that theObject is stuck with the property names it has.

    Does anybody know an efficient way of doing a case-insensitive property name lookup in a situation like this?

  • Doug Lerner
    Doug Lerner about 8 years
    That certainly looks interesting! I wonder why I'm getting a Object.getOwnPropertyNames is not a function error when I try it on my server though. I will report again after more investigation! Thanks.
  • Jelly
    Jelly about 8 years
    This can have two possibility. One is your javascript env is < ES5, That method getOwnPropertyNames is added in ES5( Object.keys can work too, you can try ). The other is you redefine getOwnPropertyNames in your code somewhere.
  • Sigfried
    Sigfried about 8 years
    How is it an improvement on mine? (This is a genuine question, I'm not being defensive. It seems a little less easy to understand, but if you buy something for that, it's worth it, but I can't tell what you're buying.)
  • HBP
    HBP about 8 years
    It may be just personal preference, but I only declare a variable when multiple references are required (theKeys in your code is referenced only once). I've gotten used to using Object.keys, it returns only enumerable keys, your code will include non-enumerable keys (which is not likely to be an issue but probably should be mentioned). The reduce method also makes it clearer (to me!) that we are generating an object.
  • Sigfried
    Sigfried about 8 years
    Thanks for elaborating. I appreciate it. I wish my brain processed reduces more quickly. I can't read them without moving my lips. :)
  • HBP
    HBP about 8 years
    You're welcome. I used to be the same but practice makes perfect ;) One reason I butt in to these questions from time to time - to show what the options are.
  • Francisco Cabral
    Francisco Cabral almost 4 years
    You say "it don't loop anything." but you used a loop... The RegExp is a loop in "theKeys". If you have 1million properties, you will loop 1million*PropertyLength. I would say that this approach could be worse than just doing a loop, but data is better than words, so I tested it. And in fact this approach is worse than a normal For loop. See the test results in: repl.it/@FranciscoCabra2/Test-GetPropValue