Search code examples
javascriptarraysjsonobjectarray-algorithms

A better way to search an object


Often times I'll find myself having to access a particular object from an object or array of objects that are indexed by arbitrary indices, but the object I need is one who's key matches a particular value.

For example:

var cars = [
    { id:23, make:'honda', color: 'green' },
    { id:36, make:'acura', color:'silver' },
    { id:18, make:'ford', color:'blue' },
    { id:62, make:'ford', color:'green' }, 
];

Suppose I need one of these entries and I know this entry unique; the one where id=18, for instance.

Right now, Im doing this in the following way:

function select(key,val,arr){

    for(var i in arr){
        if(arr[i][key]==val) return(arr[i]);
    }
    return(null); // object not present in arr
}


var id = 18;
var car = select('id', id, cars);

// car = { id:18, make:'ford', color:'blue' }

But this seems cumbersome and scales poorly as it varies in performance. A value from a large dataset may be returned very quickly, if its towards the beginning of the array or, at worst, will take as many iterations as there are entries. This also seems very wasteful if the value doesn't exist at all, since you've just iterated over all the objects just to come up with a null result.

Is there a more elegant way of searching an array or object for a value when the search criteria is not the same parameter as the subject's keys?


Solution

  • You can use the Array.prototype.map() to create a shadow array, which will help you search more fast, or furthermore you can create an index object like below, it will directly return the index you need.

    var cars = [
        { id:23, make:'honda', color: 'green' },
        { id:36, make:'acura', color:'silver' },
        { id:18, make:'ford', color:'blue' },
        { id:62, make:'ford', color:'green' }, 
    ];
    let cars_s = cars.map(function(x) {
        return x.id;
    });
    let i = cars_s.indexOf(18);
    console.log(i); // 2
    console.log(cars[i]); // { id:18, make:'ford', color:'blue' }
    
    let index = {};
    for (let i = 0; i < cars_s.length; i++) {
        index[cars_s[i]] = i;
    }
    console.log(index[18]); // 2