简体   繁体   中英

Javascript find node from tree with recursive function

I have JavaScript tree data like this.

 const tree = { children:[ {id: 10, children: [{id: 34, children:[]}, {id: 35, children:[]}, {id: 36, children:[]}]}, {id: 10, children: [ {id: 34, children:[ {id: 345, children:[]} ]}, {id: 35, children:[]}, {id: 36, children:[]} ] }, {id: 11, children: [{id: 30, children:[]}, {id: 33, children:[]}, {id: 3109, children:[]}]} ], id: 45 } const getByID = (tree, id) => { let result = null if (id === tree.id) { return tree } else { if(tree.children){ tree.children.forEach( node=> { result = getByID(node, id) }) } return result } } const find345 = getByID(tree, 345) console.log(find345)

I was try to find item by its id from this tree. im using recursive function to iterate the tree and its children, but it wont find the item as i expected.

its always return null. expected to return {id: 345, children:[]}

You need to exit the loop by using a method which allows a short circuit on find.

The problem with visiting nodes but already found the node, is the replacement of the result with a later wrong result. You need to exit early with a found node.

Array#some allows to iterate and to exit the loop if a truty value is returned. In this case the result is truthy on find.

 const tree = { children: [{ id: 10, children: [{ id: 34, children: [] }, { id: 35, children: [] }, { id: 36, children: [] }] }, { id: 10, children: [{ id: 34, children: [{ id: 345, children: [] }] }, { id: 35, children: [] }, { id: 36, children: [] }] }, { id: 11, children: [{ id: 30, children: [] }, { id: 33, children: [] }, { id: 3109, children: [] }] }], id: 45 }; const getByID = (tree, id) => { let result = null if (id === tree.id) { return tree } else { if(tree.children){ tree.children.some(node => result = getByID(node, id)); // ^^^^ exit if found // ^^^^^^^^^^^^^^^^^^^^^^^^^^ return & assign } return result; } } const find345 = getByID(tree, 345) console.log(find345)

A bit shorter

 var tree = { children: [{ id: 10, children: [{ id: 34, children: [] }, { id: 35, children: [] }, { id: 36, children: [] }] }, { id: 10, children: [{ id: 34, children: [{ id: 345, children: [] }] }, { id: 35, children: [] }, { id: 36, children: [] }] }, { id: 11, children: [{ id: 30, children: [] }, { id: 33, children: [] }, { id: 3109, children: [] }] }], id: 45 }, getByID = (tree, id) => { var temp; return tree.id === id? tree: (tree.children || []).some(o => temp = getByID(o, id)) && temp; }; console.log(getByID(tree, 345));

We can also use reduce method for recursive function

function findAllByKey(obj, keyToFind) {
  return Object.entries(obj)
    .reduce((acc, [key, value]) => (key === keyToFind)
      ? acc.concat(value)
      : (typeof value === 'object' && value)
      ? acc.concat(findAllByKey(value, keyToFind))
      : acc
    , []) || [];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM