web-dev-qa-db-fra.com

Comment trouver une valeur dans un objet/tableau multidimensionnel en Javascript?

J'ai un objet multidimensionnel (c'est en gros un tableau):

Object = {
   1 : { name : bob , dinner : pizza },
   2 : { name : john , dinner : sushi },
   3 : { name : larry, dinner : hummus }
}

Je veux être capable de rechercher l'objet/tableau où la clé est "dîner", et voir si cela correspond à "sushi".

Je sais que jQuery a $ .inArray, mais cela ne semble pas fonctionner avec les tableaux multidimensionnels. Ou peut-être que je me trompe. indexOf semble également ne fonctionner que sur un seul niveau de tableau.

N'y a-t-il aucune fonction ou code existant pour cela?

79
Questioner

Si vous avez un tableau tel que

var people = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

Vous pouvez utiliser la méthode filter d'un objet Array:

people.filter(function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

Dans les nouvelles implémentations JavaScript, vous pouvez utiliser une expression de fonction:

people.filter(p => p.dinner == "sushi")
  // => [{ "name": "john", "dinner": "sushi" }]

Vous pouvez rechercher des personnes qui ont "dinner": "sushi" à l'aide de map

people.map(function (person) {
  if (person.dinner == "sushi") {
    return person
  } else {
    return null
  }
}); // => [null, { "name": "john", "dinner": "sushi" }, null]

ou a reduce

people.reduce(function (sushiPeople, person) {
  if (person.dinner == "sushi") {
    return sushiPeople.concat(person);
  } else {
    return sushiPeople
  }
}, []); // => [{ "name": "john", "dinner": "sushi" }]

Je suis sûr que vous êtes capable de généraliser cela à des clés et des valeurs arbitraires!

178
adamse

jQuery a une méthode intégrée jQuery.grep qui fonctionne de manière similaire à la fonction ES5 filter de Réponse de @ adamse et devrait fonctionner correctement sur les navigateurs plus anciens.

En utilisant l'exemple d'Adamse:

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

vous pouvez faire ce qui suit

jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]
17
Zach Lysobey

Si vous effectuez fréquemment cette recherche, envisagez de modifier le format de votre objet afin que le dîner soit une clé. C'est un peu comme assigner une clé en cluster primaire dans une table de base de données. Donc, par exemple: 

Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }

Vous pouvez maintenant y accéder facilement comme ceci: Object['sushi']['name']

Ou si l'objet est vraiment aussi simple que cela (simplement 'name' dans l'objet), vous pouvez simplement le changer en:

Obj = { 'pizza' : 'bob', 'sushi' : 'john' }

Et puis accédez-y comme: Object['sushi'].

Il est évident que ce n'est pas toujours possible ni à votre avantage de restructurer votre objet de données de cette manière, mais le fait est que parfois, la meilleure réponse consiste à déterminer si votre objet de données est structuré de la meilleure façon. Créer une clé comme celle-ci peut être plus rapide et créer un code plus propre.

10
dallin
var getKeyByDinner = function(obj, dinner) {
    var returnKey = -1;

    $.each(obj, function(key, info) {
        if (info.dinner == dinner) {
           returnKey = key;
           return false; 
        };   
    });

    return returnKey;       

}

jsFiddle .

Tant que -1 n'est jamais une clé valide.

8
alex

Vous pouvez trouver l'objet dans un tableau avec Alasql library:

var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
     { name : "larry", dinner : "hummus" } ];

var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);

Essayez cet exemple dans jsFiddle .

2
agershun

Vous pouvez utiliser une simple boucle in:

for (prop in Obj){
    if (Obj[prop]['dinner'] === 'sushi'){

        // Do stuff with found object. E.g. put it into an array:
        arrFoo.Push(Obj[prop]);
    }
}

L'exemple de violon suivant met tous les objets contenant dinner:sushi dans un tableau:

https://jsfiddle.net/3asvkLn6/1/

1
Rotareti

Il y a déjà beaucoup de bonnes réponses ici, alors pourquoi ne pas en utiliser une autre, utilisez une bibliothèque comme lodash ou underscore :)

obj = {
   1 : { name : 'bob' , dinner : 'pizza' },
   2 : { name : 'john' , dinner : 'sushi' },
   3 : { name : 'larry', dinner : 'hummus' }
}

_.where(obj, {dinner: 'pizza'})
>> [{"name":"bob","dinner":"pizza"}]
1
TomDotTom

Je devais rechercher une structure de sitemap imbriquée pour le premier élément feuille qui machte un chemin donné. Je suis venu avec le code suivant en utilisant simplement .map().filter() et .reduce. Retourne le dernier élément trouvé qui correspond au chemin /c.

var sitemap = {
  nodes: [
    {
      items: [{ path: "/a" }, { path: "/b" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    }
  ]
};

const item = sitemap.nodes
  .map(n => n.items.filter(i => i.path === "/c"))
  .reduce((last, now) => last.concat(now))
  .reduce((last, now) => now);

 Edit 4n4904z07

0
Marc