2010-12-13 3 views
2

Je suis nouveau JavaScript et j'essaie de trouver un moyen plus facile de trouver le nom donné une valeur de l'objet littéral.En Javascript, valeur donnée, trouver le nom de l'objet littéral

par exemple.

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

Étant donné 'Accord', je veux obtenir Honda de l'objet Cars.

+0

Et si un autre fabricant avait le même modèle? Disons que Chevrolet fait un accord. –

+1

"un moyen plus facile" que quoi? Pourquoi ne publiez-vous pas comment vous le faites maintenant? En passant, il n'y a probablement pas de moyen plus simple, à moins que vous ne puissiez utiliser une bibliothèque qui pourrait vous aider. –

Répondre

3

Vous devez faire une boucle à travers, comme ceci:

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, pour la même de cross-browser de travail, cela ne tient pas l'existence de .indexOf() depuis IE ne l'a pas ... 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"; 
} 
+0

Juste curieux ... est le cars.hasOwnProperty redondant? –

+0

@SB - Non, pas si quelqu'un a joué avec le prototype de l'objet ... mieux vaut être sûr IMO –

+0

@SB: À ce stade, il s'agit principalement de la programmation culte de la cargaison. La théorie est qu'il est sûr de le faire, mais pas nécessairement sûr de ne pas le faire. Voir la note de bas de page à ma réponse pour les raisons possibles pourquoi il ne peut pas être sûr de le faire. Indice: hasOwnProperty vous dira si la propriété est héritée ou non. – slebetman

1

Si vous allez le faire une fois, utilisez une fonction comme celle donnée par Bobby. Si vous allez faire ça plusieurs fois alors je vous suggère de créer une cartographie inverse des voitures aux fabricants:

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 pour ceux qui ont les doigts qui piquent downvoting: Pour les objets qui ne héritent pas quoi que ce soit donné dans l'OP un contrôle hasOwnProperty ici est inutile. Pour les objets qui héritent, cela dépend du programmeur. Si vous voulez que la composabilité soit héritée, alors un contrôle hasOwnProperty est exactement ce que vous ne voulez pas. Si vous ne vous souciez pas de l'héritage, utilisez un contrôle hasOwnProperty, mais si c'est le cas, vous n'hériteriez pas en premier lieu, ce qui rendrait inutile une vérification hasOwnProperty. Dans les rares cas où vous êtes contraint de créer l'objet via l'héritage mais que vous ne voulez pas vérifier les attributs du parent, vous devez effectuer une vérification hasOwnProperty. Bien sûr, si vous utilisez une bibliothèque comme Prototype.js qui insiste sur la modification de l'objet Object, alors je suis désolé pour vous parce que vous êtes obligé de faire une vérification hasOwnProperty.

+0

Cela n'aurait pas le même résultat, il est à noter que si 2 constructeurs fabriquaient la même voiture, cela retournerait le * dernier * , plutôt que le * premier *, les deux positions étant relatives à l'ordre de la propriété de l'objet ... ce qui n'est pas garanti. –

+0

@Nick: Ah, mais si nous parlons ici de voitures, il est fort probable que les noms des modèles soient uniques. De même, d'autres domaines de problème peuvent également avoir cette propriété. De plus, la propriété de l'objet a un ordre aléatoire (du moins en théorie), donc parler de "premier" ou de "dernier" n'a aucun sens si vous ne commencez pas par trier le nom du fabricant. (testé, sur firefox au moins la propriété d'objet ne vient pas nécessairement dans l'ordre de création quand on fait une boucle for..in, ce n'est pas PHP) – slebetman

-1

Maintenir une cartographie distincte des modèles pour les fabricants.

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++; 
     } 
    } 
} 
+0

Plus de code: Yay! Espérons d'une structure de données permettant la cartographie bi-directionnelle (bidirectionnelle) des clés de valeurs, et vice versa –

+0

@George - pardonnez-moi de ne pas comprendre ... pourquoi suggérez-vous l'approche de la structure de données? Je ne vois pas comment cela serait mieux dans ce cas. (Je suppose que c'est pour la réutilisation). –

+0

Oui, pour réutilisation. Peut-être un objet personnalisé qui encapsule la structure de données d'origine et celle que vous proposez. Mais certainement une façon d'associer les deux afin qu'ils ne soient pas dans la portée globale sans relation les uns avec les autres. –

Questions connexes