Javascript使用递归函数从树中查找节点

时间:2018-03-15 10:31:56

标签: javascript tree iterator

我有JavaScript这样的树数据。

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)

我试图通过它的id从这棵树中找到项目。我使用递归函数迭代树及其子,但它不会像我预期的那样找到项目。

它总是返回null。预计会返回{id: 345, children:[]}

2 个答案:

答案 0 :(得分:1)

您需要使用允许查找短路的方法退出循环。

访问节点但已找到节点的问题是用稍后错误的结果替换结果。您需要使用找到的节点提前退出。

如果返回truty值,

Array#some允许迭代并退出循环。在这种情况下,结果是真正的查找。

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)

稍短一点

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));

答案 1 :(得分:-1)

我们也可以对递归函数使用reduce方法

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
    , []) || [];
}