Search code examples
javascriptarraysjavascript-objects

Delete nested obejct property by "path" array


Let's say I have an object like this:

var test = {
    foo: {
        bar: {
            qwe: 123,
            abc: ['x','y','z']
        }
    }
};

I would like to be able to dynamically delete any property I want using an array representing the "path" if you will.

Let me explain:

deleteProp(test,['foo','bar','qwe']);

should delete test.foo.bar.qwe. Just like delete test.foo.bar.qwe; would.

This is what I've tried:

function deleteProp(obj, pathSegments) {
    let lastSubObj = obj
    pathSegments.forEach((segment,i)=>{
        lastSubObj = lastSubObj[segment] = (i === pathSegments.length-1) ? undefined : {};
    });
    lastSubObj = undefined;
    return obj;
}

But it results in:

{
    foo: {
        bar: {
            qwe: undefined
        }
    }
}

So the property is not actually deleted and in addition to that the abc property is gone now.


Solution

  • You could reduce the object by walking the path. Before walking save the last property as key for deleting the object.

    The callback uses a default object if a property is not in the object.

    function deleteProp(object, path) {
        var last = path.pop();
        delete path.reduce((o, k) => o[k] || {}, object)[last];
    }
    
    var test = { foo: { bar: { qwe: 123, abc: ['x','y','z'] } } };
    
    deleteProp(test, ['foo', 'bar', 'qwe']);
    console.log(test);