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?
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!
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" }]
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.
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.
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 .
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:
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"}]
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);