J'ai ce tableau:
[
{
id: 1,
name: 'test 1',
children: []
},
{
id: 2,
name: 'test 2',
children: [
{
id: 4,
name: 'test 4'
}
]
},
{
id: 3,
name: 'test 3',
children: []
}
]
Comment puis-je filtrer par la propriété id
dans ce tableau et les tableaux children
imbriqués?
Par exemple, la recherche de id = 3
, devrait renvoyer le test 3
objet et recherche de id = 4
devrait renvoyer le test 4
objet.
En utilisant lodash, vous pouvez faire quelque chose comme ceci:
_(data)
.thru(function(coll) {
return _.union(coll, _.pluck(coll, 'children'));
})
.flatten()
.find({ id: 4 });
Ici, thru () est utilisé pour initialiser la valeur encapsulée. Il renvoie l'union du tableau d'origine et des enfants imbriqués. Cette structure de tableau est ensuite aplatie à l'aide de flatten () , vous pouvez donc find () l'élément.
C'est une tâche très simple traversée de l'arbre . La façon la plus simple de le résoudre est la récursivité (lien vers jsbin ). Cela fonctionnera avec n'importe quelle profondeur (avec une limite de récursion bien sûr) et c'est l'un des moyens les plus rapides avec la pire complexité O (n):
function find(id, items) {
var i = 0, found;
for (; i < items.length; i++) {
if (items[i].id === id) {
return items[i];
} else if (_.isArray(items[i].children)) {
found = find(id, items[i].children);
if (found) {
return found;
}
}
}
}
Pour trouver toutes les correspondances - une fonction légèrement modifiée (le lien jsbin ci-dessus est mis à jour):
function findAll(id, items) {
var i = 0, found, result = [];
for (; i < items.length; i++) {
if (items[i].id === id) {
result.Push(items[i]);
} else if (_.isArray(items[i].children)) {
found = findAll(id, items[i].children);
if (found.length) {
result = result.concat(found);
}
}
}
return result;
}
Une autre option lodash
avec clé enfant et niveaux illimités en profondeur.
const flattenItems = (items, key) => {
return items.reduce((flattenedItems, item) => {
flattenedItems.Push(item)
if (Array.isArray(item[key])) {
flattenedItems = flattenedItems.concat(flattenItems(item[key], key))
}
return flattenedItems
}, [])
}
const item = find(flattenItems(items, 'children'), ['id', 4])