简体   繁体   中英

Javascript implement deep filtering in nested json data

I have the following data structure

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
  }
  ]
}
]

With unlimited level of nesting, only leaf tasks have the flag completed and I need to filter out only those tasks which are completed and keep them with their parents.

I look at lodash but it does not seem to have a deep filter. I am now thinking about using a tree traversal to filter out the tasks.

Is there an easy way to implement something like this with lodash ?

You wanted a lodash solution. I believe this recursive function does the trick.

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

well, what you want can be acheive by a recussive function, however (because you want easy solution) here is a solution with a callback as a second argument with JSON.parse and we will parse it from string; But, please note, easy dosen't always meant performance efficient!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM