Pour un objet de cette structure:
findObj(obj, id) {
if (obj.id === id) {
return obj;
}
obj.forEach(x => {
if (x.id === id) {
return x;
} else {
this.findObj(x.children, id);
}
});
}
Comment obtenir un objet par valeur (id)? Donc je cherche une fonction où si j'appelle ceci:
{
id: 3,
name: '3',
children: []
}
Cela renverrait ceci:
findObj(myObj, 3);
Un autre exemple:
{
id: 6,
name: '6',
children: [
{
id: 7,
name: '7',
children: []
}
]
}
Renvoyer ceci:
findObj(myObj, 6);
Je sais que j'ai besoin d'une fonction de récursivité. Voici ce que j'ai jusqu'à présent:
const myObj = {
id: 1,
name: '1',
children: [
{
id: 2,
name: '2',
children: [
{
id: 3,
name: '3',
children: []
}
]
},
{
id: 4,
name: '4',
children: [
{
id: 5,
name: '5',
children: [
{
id: 6,
name: '6',
children: [
{
id: 7,
name: '7',
children: []
}
]
}
]
}
]
},
]
}
(Ceci est dans une classe angulaire)
3 Réponses :
Deux problèmes:
return x; retourne uniquement à partir du rappel forEach , pas de la fonction findObj . N'utilisez pas forEach ! Une simple boucle for… of fera l'affaire Je suppose que vous ne cherchez pas une solution complète, alors je laisse cela comme un exercice :-)
Vous pouvez vérifier l'objet ou vérifier les enfants.
.as-console-wrapper { max-height: 100% !important; top: 0; }
function find(object, id) {
var result;
if (object.id === id) return object;
object.children.some(o => result = find(o, id));
return result;
}
const object = { id: 1, name: '1', children: [{ id: 2, name: '2', children: [{ id: 3, name: '3', children: [] }] }, { id: 4, name: '4', children: [{ id: 5, name: '5', children: [{ id: 6, name: '6', children: [{ id: 7, name: '7', children: [] }] }] }] }] };
console.log(find(object, 5));
console.log(find(object, 6));
À première vue, je vois quelques problèmes.
Si vous avez déjà le ob.id === id dans la fonction, vous n'avez pas besoin de le vérifier plus tard. De plus, si findObj est une fonction définie dans la portée comme n'importe quelle autre variable et n'est pas dans la définition "class", vous n'avez pas besoin de l'appeler via this , de la même manière que le premier appel à findObj vous le faites sans le mot-clé this .
De plus, au début, vous passez un objet à votre méthode, mais ensuite vous passez un tableau d'objets (le obj.children ), et vous vérifiez également l'id dans une méthode forEach , où vous passez une fonction (le x => {... thingy), donc quand vous revenez, vous revenez de cette fonction au lieu de la fonction principale.
Je l'ai corrigé pour vous. Je vous recommande de comprendre ce qui se passe et d'en tirer des leçons, car cela ne se produira pas si vous savez ce que vous faites (le débogage est votre maître ici).
findObj(obj, id) {
if (obj.id === id) {
return obj;
}
for (var i = 0; i < obj.children.length; i++) { // No forEach, so when we return, we actually return from findObj
var r = findObj(obj.children[i], id); // We see if we have any return and let the "check logic" be defined on one location instead of duplicated.
if (r) {
return r;
}
}
}
Il existe également de bonnes alternatives, comme décrit dans le Documentation forEach MDN : Il n'y a aucun moyen d'arrêter ou de rompre une boucle forEach () autrement qu'en lançant une exception. Si vous avez besoin d'un tel comportement, la méthode forEach () n'est pas le bon outil.
la recherche du parent est trompeuse, car vous recherchez l'élément lui-même. btw, qu'avez-vous essayé?
ouais ive a édité ma réponse juste maintenant haha @NinaScholz
Considérez ce que cela signifie dans la fonction parent si vous
retournezdepuis une fonction de rappel. Considérez ensuite ce que faitArray # forEach.J'implémente une solution générique
deepFinddans ce Q&R . Je pense que vous le trouverez utile: D