JS | lodash:从深层嵌套数组

时间:2016-03-08 18:26:57

标签: javascript lodash

下面是一个从深层嵌套数组中删除注释的递归方法。代码有效,但这是我的问题:

问题:

  1. 我在循环中使用_.remove来查找和删除当前数组中的注释。由于显而易见的原因,即循环内的循环,它似乎很昂贵,但其他方法似乎同样昂贵。我确信有更好的方法可以做到这一点。
  2. 工作示例:

    https://plnkr.co/edit/PeW5ZFLynO2q8VNqbAHx?p=preview

        var comments = [
            {
                id: 1,
                depth: 0,
                subject: 'Subject one'
            },
            {
                id: 2,
                depth: 0,
                subject: 'Subject two',
                children: [
                    {
                        id: 3,
                        depth: 1,
                        subject: 'Subject two dot one'
                    },
                    {
                        id: 4,
                        depth: 1,
                        subject: 'Subject two dot two'
                    }
                ]
            },
            {
                id: 5,
                depth: 0,
                subject: 'Subject three',
                children: [
                    {
                        id: 6,
                        depth: 1,
                        subject: 'Subject three dot one'
                    },
                    {
                        id: 7,
                        depth: 1,
                        subject: 'Subject three dot two',
                        children: [
                            {
                                id: 8,
                                depth: 2,
                                subject: 'Subject three dot two dot one'
                            },
                            {
                                id: 9,
                                depth: 2,
                                subject: 'Subject three dot two dot two'
                            }
                        ]
                    }
                ]
            }
        ];
    
        function deleteComment(comment, comments) {
            var self = this,
                db = [];
    
            function removeComment(items, parent) {
                _.forEach(items, function (item) {
    
                    // QUESTION - seems expensive as we have a loop in a loop
                    _.remove(items, function(item) {
                        if (item.id === comment.id) {
                          console.log(item);
                          return true;
                        }
                        // NOTE: use above for demo purposes
                        // return item.id === comment.id
                    });
    
                    _.has(item, 'children')  ? removeComment(item.children, item) : 0;
                });
            }
    
          removeComment(comments, db);
    
        }
    
        var commentToBeDeleted = {           
            id: 8,
            depth: 2,
            subject: 'Subject three dot two dot one'
          };
    
        deleteComment(commentToBeDeleted, comments);
    

2 个答案:

答案 0 :(得分:1)

你可能会找到一种方法来更有效地使用.reduce()函数来组合.forEach和_.remove。但是,如果代码有效,它就可以了!

答案 1 :(得分:1)

我不确定这是否是最有效的方法,但这是我发现的最简洁的方式:

事实证明JSON.stringify为每个被转换的JSON值提供回调,您可以使用它来确定该值是否应包含在字符串中。您可以使用它来访问每个值,而无需自己遍历。

来自MDN

  

replacer参数可以是函数,也可以是数组。作为一个   函数,它需要两个参数,键和值   字符串化。发现密钥的对象是作为   replacer的这个参数。最初用空键调用它   表示正在进行字符串化的对象,然后调用它   对象或数组上的每个属性都是字符串化的。这应该   返回应添加到JSON字符串的值

在您的情况下,该功能看起来像

function deleteComment(commentToBeDeleted, comments) {
    return JSON.parse(JSON.stringify(comments, function(key, value) {
        if (commentToBeDeleted.id !== value.id) {
            return value;
        } 
    }));
}

注意:您可能不希望使用此代码,因为它留下了一个空节点,但是,您可以将您喜欢的逻辑插入到回调中,这应该可以帮助您开始。