JavaScript deep remove object property by using another object as selector

Viewed 298

I have object like this:

var myObj = {
    first: {
        sub: {
            prop1: "some text",
            prop2: "some more text"
        },
        sub2: {
            prop1: "Something",
            prop2: "Something2",
        }
    },
    second: {
        stuff: "More stuff...lots of stuff"
    }
}

I'm trying to remove property from this object by using another object as selector. For example:

var delSeletor = {
    first: {
        sub: {
            prop2: ""
        }
    }
}

So delete( delSelector, myObject) should return:

var myObj = {
    first: {
        sub: {
            prop1: "some text",
        },
        sub2: {
            prop1: "Something",
            prop2: "Something2",
        }
    },
    second: {
        stuff: "More stuff...lots of stuff"
    }
}

Please note that I'm not looking for solution using the ".dot" selector eg: delete('first.sub.prop2', myObj) like shown in this thread.

3 Answers

We now use object-scan for data processing tasks like this. It's very powerful once you wrap your head around it. Here is how you'd solve your question.

Note:

  • First we scan the first selector object and extract the paths. Then we use the paths to delete the corresponding targets.
  • This would work for arrays as well with minor modifications

// const objectScan = require('object-scan');

const prune = (sel, input) => {
  const needles = objectScan(['**'], {
    joined: true,
    filterFn: ({ value }) => typeof value === 'string'
  })(sel);
  return objectScan(needles, {
    rtn: 'count',
    filterFn: ({ parent, property }) => {
      delete parent[property];
    }
  })(input);
};

const myObj = { first: { sub: { prop1: 'some text', prop2: 'some more text' }, sub2: { prop1: 'Something', prop2: 'Something2' } }, second: { stuff: 'More stuff...lots of stuff' } };

const delSeletor = { first: { sub: { prop2: '' } } };

console.log(prune(delSeletor, myObj)); // return deletion counts
// => 1
console.log(myObj);
// => { first: { sub: { prop1: 'some text' }, sub2: { prop1: 'Something', prop2: 'Something2' } }, second: { stuff: 'More stuff...lots of stuff' } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

Disclaimer: I'm the author of object-scan

Related