【问题标题】:Javascript find node from tree with recursive functionJavascript使用递归函数从树中查找节点
【发布时间】:2018-03-15 10:31:56
【问题描述】:

我有 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:[]}

【问题讨论】:

    标签: javascript tree iterator


    【解决方案1】:

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

    访问节点但已经找到节点的问题是用后来的错误结果替换结果。您需要在找到节点的情况下提前退出。

    Array#some 允许迭代并在返回 truty 值时退出循环。在这种情况下,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)

    短一点

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

    【讨论】:

      【解决方案2】:

      递归函数也可以使用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
          , []) || [];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-30
        • 1970-01-01
        • 2019-11-24
        • 2016-05-15
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        相关资源
        最近更新 更多