Reputation: 33
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
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
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
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