递归维护JavaScript中的祖先/父代嵌套对象

Recursion maintaining ancestors/parents nested object in JavaScript

本文关键字:嵌套 对象 祖先 维护 JavaScript 递归      更新时间:2023-09-26

我有一个非常深的嵌套类别结构,并且我得到了一个可以存在于任何深度的类别对象。我需要能够遍历所有类别节点,直到找到请求的类别,并且能够始终捕获其父类别。

数据结构

[
{
    CategoryName: 'Antiques'
},
{
    CategoryName: 'Art',
    children: [
        {
            CategoryName: 'Digital',
            children: [
                {
                    CategoryName: 'Nesting..'
                }
            ]
        },
        {
            CategoryName: 'Print'
        }
    ]
},
{
    CategoryName: 'Baby',
    children: [
        {
            CategoryName: 'Toys'
        },
        {
            CategoryName: 'Safety',
            children: [
                {
                    CategoryName: 'Gates'
                }
            ]
        }
    ]
},
{
    CategoryName: 'Books'
}

]

代码当前到位

function findCategoryParent (categories, category, result) {
    // Iterate through our categories...initially passes in the root categories
    for (var i = 0; i < categories.length; i++) {
        // Check if our current category is the one we are looking for
        if(categories[i] != category){
            if(!categories[i].children)
                continue;
            // We want to store each ancestor in this result array
            var result = result || [];
            result.push(categories[i]);
            // Since we want to return data, we need to return our recursion
            return findCategoryParent(categories[i].children, category, result);
        }else{
            // In case user clicks a parent category and it doesnt hit above logic
            if(categories[i].CategoryLevel == 1)
                result = [];
            // Woohoo...we found it
            result.push(categories[i]);
            return result;
        }
    }
}

问题

  1. 如果我返回递归函数,它将适用于"Art"及其所有子函数。。但自从它回来后,类别"宝贝"永远不会被击中,因此永远不会找到"宝贝/安全/盖茨"的"盖茨"

  2. 如果我不返回递归函数,它只能返回根级节点

如有任何建议或建议,不胜感激。

好吧,我相信我找到了一个似乎对我有效的解决方案,但不确定为什么我的大脑花了这么长时间才弄清楚。。。但解决方案当然是关闭。

本质上,我使用闭包来保持作用域递归,并维护它在中进行的每一次迭代

var someobj = {
    find: function (category, tree, path, callback) {
        var self = this;
        for (var i = tree.length - 1; i >= 0; i--) {
            // Closure will allow us to scope our path variable and only what we have traversed
            // in our initial and subsequent closure functions
            (function(){
                // copy but not reference
                var currentPath = path.slice();
                if(tree[i] == category){
                    currentPath.push({name: tree[i].name, id: tree[i].id});
                    var obj = {
                        index: i,
                        category: category,
                        parent: tree,
                        path: currentPath
                    };
                    callback(obj);
                }else{
                    if(tree[i].children){
                        currentPath.push({name: tree[i].name, id: tree[i].id});
                        self.find(category, tree[i].children, currentPath, callback);
                    }
                }
            })(tree[i]);
        }
    },
    /**
     * gets called when user clicks a category to remove
     * @param  {[type]} category [description]
     * @return {[type]}          [description]
     */
    removeCategory: function (category) {
        // starts the quest for our category and its ancestors
        // category is one we want to look for
        // this.list is our root list of categoires,
        // pass in an intial empty array, each closure will add to its own instance
        // callback to finish things off
        this.find(category, this.list, [], function(data){
            console.log(data);
        });
    }
}

希望这能帮助其他需要遍历javascript对象和维护父级祖先的人。