A deep-path setter writes a value at a nested location described by a path like a.b.c, creating any missing objects and arrays on the way down. This is the job of lodash's _.set and _.unset: you hand them an object, a path, and (for set) a value, and they reach deep into the structure for you. The catch that makes them interesting is that the path is data — a string you have to parse, or an array of keys — and half the missing structure has to be conjured up as you go.
Build the two as methods on one object, objectPathSet = { set, unset }. Do not call the real lodash; parse the path and walk the object yourself.
set(obj, path, value) // writes value at a deep path, creating containers; mutates and returns obj
unset(obj, path) // deletes the value at a deep path; returns true when it is gone
const { set, unset } = objectPathSet;
set({}, 'a.b.c', 1); // { a: { b: { c: 1 } } } (objects created)
set({}, 'a[0].b', 1); // { a: [ { b: 1 } ] } (a is an ARRAY — next key is 0)
set({ a: { keep: 1 } }, 'a.added', 2); // { a: { keep: 1, added: 2 } } (sibling untouched)
set({ a: 5 }, 'a.b', 1); // { a: { b: 1 } } (the 5 is overwritten)
const obj = { list: [10, 20, 30] };
unset(obj, 'list[1]'); // true — obj.list is now [10, <hole>, 30], length still 3
unset({ a: {} }, 'a.b.c'); // true — the path was already absent, nothing thrown
'a.b.c'), array-index brackets ('a[0].b'), or a plain numeric segment ('a.0.b'), and also a ready-made array of keys like ['a', 0, 'b'].set finds a non-object where it needs to descend, it overwrites it with a container, so set({ a: 5 }, 'a.b', 1) gives { a: { b: 1 } }.unset returns true because the target is already gone (the lodash 4 rule).