Key Paths of a Nested Object
Return the path to every primitive in a nested object or array.
| Input | Output |
|---|---|
{ a: { b: { c: 1 }, d: 2 }, e: 3 } | ["a.b.c", "a.d", "e"] |
[1, { a: 2, b: [3, 4] }, 5] | ["0", "1.a", "1.b.0", "1.b.1", "2"] |
Rules
- A path joins keys with dots, and array indices are keys too.
- A primitive is anything that is not an object, plus
null. Empty objects and arrays contribute nothing. - Paths come out in visiting order: insertion order for objects, index order for arrays.
- The input is always an object or an array.
- Inputs may contain cycles. Skip a reference to an object that is already on the current path. The same object reached along two different paths is listed under both.
Hints
Hint 1
Recurse with the path so far. typeof null is "object", so test value === null first.
Hint 2
Object.keys returns index strings for arrays, so one loop covers both shapes.
Hint 3
For cycles, keep a Set of the objects on the current path: add before descending, delete after. A visited set that never forgets would drop the second path to a shared object.