简体   繁体   中英

efficient way to search an associative, multi-dimensional array (object) using JavaScript and/or jQuery for key based on value

I have an object that looks similar to this:

var arr = {};

arr.planes = { prop1 : 'a', prop2 : 'b', prop3 : 'c' };
arr.trains = { prop1 : 'x', prop2 : 'y', prop3 : 'z' };
arr.autos = { prop1 : 'red', prop2 : 'orange', prop3 : 'blue' };

I am trying to write a function (that is fast and efficient) that will return the key (or array of keys if there are more than 1) of the outer-most array based on a key/value pair nested within. Something like:

function getKey(obj, prop, val) {
   // do some stuff...
   return key;
}

var myKey = getKey(arr, 'prop2', 'orange');

The value of myKey should be "autos".

I'm pretty sure this can be done with a couple of nested for loops but these arrays are rather large and I'm thinking that, especially using jquery's grep(), there has to be a better way... or maybe not - I'm just stumped at the moment.

Any insight would be greatly appreciated!!

Other than changing your data structure like chris suggests this is pretty much your only option:

function getKey(obj, prop, val) {
    var keys = [];

    for (var key in obj) {
        if (obj[key].hasOwnProperty(prop) && obj[key][prop] === val) {
            keys.push(key);                
        }            
    }

    return keys;
}

Nested loops are not required and you only go over each array element once.. pretty efficient in my opinion.

You might be surprised how fast a for loop can execute over an array in modern browsers.

But, you can also maintain different data structures for this.
Just use some loops to build a new object structured like so

var map = {
    prop1: {a: ["planes"], x: ["trains"], red: ["autos"]}
  , prop2: {...}
};

function getKey(prop, val) {
   return map[prop][val] || [];
}

then lookups are extremely fast from that point on.

I assume the values are scalar, otherwise this wont work because only scalars can be used as property names.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM