递归在JavaScript中维护祖先/父类嵌套对象

时间:2014-09-09 18:08:35

标签: javascript recursion

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

数据结构

[
{
    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&#39; Art&#39;和它的所有孩子......但是自从它返回以来,宝贝类别永远不会被击中,因此永远不会找到生活在婴儿/安全/门的&#39;

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

  3. 非常感谢任何建议或建议。

1 个答案:

答案 0 :(得分:0)

好吧,我相信我找到了一个似乎对我有用的解决方案,并且不确定为什么我的大脑需要这么长时间来解决它...但解决方案当然是关闭的。

基本上我使用闭包来保持一个范围的递归并保持它已遍历的每次迭代

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对象并维护父祖先。