Search code examples
ecmascript-6lodash

Lodash: Find and delete an item in a multi-level Json based on a conditions


I am trying to delete an item in an "roles array" based on a condition, but this array is an item in a json array. Also I have to check one more condition at the parent level before looking in to the roles array. I tired lodash's find to first match the first condition at the parent level, but couldn't able to proceed further with the next level of filtering.

My json:

[ {"unitId": "2", name: "elizabeth", roles: [{ "role":{"roleId" : "2", roleName: "testing"}},  { "role":{"roleId" : "5", roleName: "dev"}}]},
{"unitId": "2", name: "peter", roles: [{ "role":{"roleId" : "1", roleName: "testing"}},  { "role":{"roleId" : "2", roleName: "dev"}}]}
]

Expected result:

[ {"unitId": "2", name: "elizabeth", roles: [{ "role":{"roleId" : "2", roleName: "testing"}}}]},
{"unitId": "2", name: "peter", roles: [{ "role":{"roleId" : "1", roleName: "testing"}},  { "role":{"roleId" : "2", roleName: "dev"}}]}
]

Here I need to first check for unitId : 2, and then delete any roles with roleId: 5 in that unitId: 2


Solution

  • You can use map & remove with lodash:

    const data = [{ unitId: "2", name: "elizabeth", roles: [{ "role": { "roleId": "2", roleName: "testing" } }, { "role": { "roleId": "5", roleName: "dev" } }] }, { unitId: "2", name: "peter", roles: [{ "role": { "roleId": "1", roleName: "testing" } }, { "role": { "roleId": "2", roleName: "dev" } }] } ]
    
    const result = _.map(data, x => (_.isEqual(x.unitId, "2") ? 
       _.remove(x.roles, y => y.role.roleId == "5") : null, x))
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    You could also skip lodash and do:

    const data = [{ unitId: "2", name: "elizabeth", roles: [{ "role": { "roleId": "2", roleName: "testing" } }, { "role": { "roleId": "5", roleName: "dev" } }] }, { unitId: "2", name: "peter", roles: [{ "role": { "roleId": "1", roleName: "testing" } }, { "role": { "roleId": "2", roleName: "dev" } }] } ]
    
    const result = data.map(x => (x.roles = x.unitId == "2" ? 
      x.roles.filter(y => y.role.roleId != '5') : x.roles, x))
    
    console.log(result)

    With using map and filter