Al1
Al1

Reputation: 33

In Javascript, given value, find name from Object literal

I'm new JavaScript and trying to find out an easier way to find name given a value from object literal.

e.g.

var cars ={ Toyata: ['Camry','Prius','Highlander'],
            Honda:  ['Accord', 'Civic', 'Pilot'],
            Nissan: ['Altima', 'Sentra', 'Quest']};

Given 'Accord', I want to get Honda from the object Cars.

Upvotes: 3

Views: 3671

Answers (3)

slebetman
slebetman

Reputation: 113926

If you're going to be doing this once, then use a function like the one given by Bobby. If you're going to be doing this multiple times then I'd suggest creating a reverse mapping of cars to manufacturers:

var manufacturers = {};

// create a map of car models to manufacturers:
for (var manf in cars) {
    /* see note below */

    for (var i=0; i<cars[manf].length; i++) {
        manufacturers[cars[manf][i]] = manf;
    }
}

// Now referencing the manufacturers is 
// a very fast hash table lookup away:

var model = 'Accord';
alert(manufacturers[model]);

note for those with itchy downvoting fingers: For objects that don't inherit anything as given in the OP a hasOwnProperty check here is unnecessary. For objects that do inherit it depends on the programmer. If you want composability via inheritance then a hasOwnProperty check is exactly what you DONT want. If you don't care about inheritance then use a hasOwnProperty check but if so you would not be inheriting in the first place which would make a hasOwnProperty check unnecessary. In the rare case where you are forced to create the object via inheritance but don't want to check the parent's attributes then you should do a hasOwnProperty check. Of course, if you use a library like Prototype.js that insists on modifying the Object object then I feel sorry for you because you are forced to do a hasOwnProperty check.

Upvotes: 2

Sean Vieira
Sean Vieira

Reputation: 159955

Maintain a separate mapping of models to manufacturers.

var cars ={ Toyata: ['Camry','Prius','Highlander'],
            Honda:  ['Accord', 'Civic', 'Pilot'],
            Nissan: ['Altima', 'Sentra', 'Quest']};

var models = {};
var hasOwnProperty = Object.prototype.hasOwnProperty;
for (key in cars) {
    if (hasOwnProperty.call(cars, key)) {
        var i=0,l=cars[key].length,manufacturer=cars[key];
        while (i<l) {
            if ( ! hasOwnProperty.call(models, manufacturer)) {
                models[manufacturer] = key;
            } else {
                // Throw an error, or change the value to an array of values
            }
            i++;
        }
    }
}

Upvotes: 0

Nick Craver
Nick Craver

Reputation: 630469

You would need to loop through, like this:

function getManufacturer(carName) {
    for(var key in cars) {
        if(cars.hasOwnProperty(key)) {
           for(var i=0; i<cars[key].length; i++) {
              if(cars[key][i] == carName) return key;
           }
        }
    }
    return "Not found";
}

You can test it out here, for the same of working cross-browser, this ignores the existence of .indexOf() since IE doesn't have it...that version would look like this:

function getManufacturer(carName) {
    for(var key in cars) {
        if(cars.hasOwnProperty(key) && cars[key].indexOf(carName) != -1) {
            return key;
        }
    }
    return "Not found";
}

Upvotes: 4

Related Questions