Object Path set / unsetLoading saved progress…

Object Path set / unset

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.

Signature

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

Examples

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

Notes

  • Path forms — accept a string with dot notation ('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'].
  • Auto-create the right container — a missing intermediate becomes an array when the next key is a non-negative integer, otherwise a plain object.
  • Primitive in the middle — if 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 never creates — walking a path that does not exist is a no-op; unset returns true because the target is already gone (the lodash 4 rule).
  • unset uses delete — removing an array index leaves a hole rather than shifting the rest, so the array keeps its length.
  • Do not use lodash — implement the string parsing and the walk by hand; that is the whole exercise.

FAQ

How does set decide whether to create an array or an object for a missing level?
It looks at the NEXT key in the path. If that key is a non-negative integer (a number, or a numeric string like '0'), set creates an array; otherwise it creates a plain object. So 'a.0.b' makes a an array and 'a.b' makes a an object.
What does set do when a value in the middle of the path is a primitive?
It overwrites it, matching lodash. set({ a: 5 }, 'a.b', 1) replaces the 5 with a fresh object and returns { a: { b: 1 } } — a primitive cannot hold a nested key, so it is swapped for the right container.
When does unset return false?
Almost never. Following lodash 4, unset returns true whenever the property is gone after the call — whether it deleted an existing key or the key was already absent. It only returns false for a non-configurable property that delete cannot remove.
Does unset on an array index shift the other elements?
No. It uses delete, which removes the slot but leaves a hole, so the array keeps its length and the other indices do not move. Use splice instead if you want the elements to shift down.
Loading editor…