Javascript在嵌套的json数据中实现深度过滤

时间:2017-08-21 13:36:43

标签: javascript lodash

我有以下数据结构

tasks = [{
   id: 1,
   name: "task1",
   subtasks: [
      {
         id: 4,
         name: "task2",
         subtasks: [{
            id: 11,
            name: "task to remove",
            completed: false
         }]
      },
      {
         id: 6,
         name: "task to remove",
         subtasks: []
      },
      {
         id: 7,
         name: "parent task to keep",
         subtasks: [{
            id: 11,
            name: "task to keep",
            completed: true
         }]
      }
   ]
},
{
  id: 44,
  name: "task to keep",
  subtasks: [{
    id: 55,
    name: "task to keep",
    completed: true
  },
  {
    id: 66,
    name: "task to delete",
    completed: false
  }
  ]
}
]

无限级别的嵌套,只有叶子任务完成了标记,我只需要过滤掉那些完成的任务并将它们与父母保持一致。

我看看lodash,但似乎没有深层过滤器。我现在正在考虑使用树遍历来过滤掉任务。

有没有一种简单的方法可以用lodash实现这样的东西?

2 个答案:

答案 0 :(得分:0)

你想要一个lodash解决方案。我相信这种递归函数可以解决问题。

function completed (task) {
    // if it is a leaf node, just return true when it is completed
    if (_.has(task,'completed')) {
        return task.completed;
    }

    // if it has subtasks, then use our filter on all the subtasks ...
    if (_.has(task,'subtasks')) {
        task.subtasks = _.filter(task.subtasks, completed);

        // ... and only return true if there are subtasks left after filtering
        return task.subtasks.length;
    }

}

console.log(_.filter(tasks,completed));

答案 1 :(得分:0)

好吧,你想要的东西可以通过一个回避函数实现,但是(因为你想要简单的解决方案)这里是一个带有回调作为JSON.parse的第二个参数的解决方案,我们将从字符串中解析它;但是,请注意,轻松选择并不总是意味着效率高!



//your data
tasks = [{
        id: 1,
        name: "task1",
        subtasks: [{
                id: 4,
                name: "task2",
                subtasks: [{
                    id: 11,
                    name: "task to remove",
                    completed: false
                }]
            },
            {
                id: 6,
                name: "task to remove",
                subtasks: []
            },
            {
                id: 7,
                name: "parent task to keep",
                subtasks: [{
                    id: 11,
                    name: "task to keep",
                    completed: true
                }]
            }
        ]
    },
    {
        id: 44,
        name: "task to keep",
        subtasks: [{
                id: 55,
                name: "task to keep",
                completed: true
            },
            {
                id: 66,
                name: "task to delete",
                completed: false
            }
        ]
    }
]

//solution
var finalTasks = JSON.parse(JSON.stringify(tasks), (k, v) => {
    if (Array.isArray(v)) {
        return v.filter(u => u);
    } else if (typeof v === "object" && !(v.subtasks && v.subtasks.length) && !v.completed) {
        return undefined;
    }
    return v;
});

console.log(finalTasks);