Implement squashObject(obj). It turns a nested object into a flat object with one key per leaf value. A leaf is any value that is not a plain object or an array. The key is the path to the leaf, with the keys along the way joined by dots.
Rules:
- Plain objects and arrays are walked into. Arrays use their indexes as keys:
{ tags: ["x"] }gives{ "tags.0": "x" }. - Every other value is a leaf and is kept as it is, including
null,undefined, dates and functions. - Empty keys (
"") are left out of the path:{ a: { "": { b: 1 } } }gives{ "a.b": 1 }. If every key on the path is empty, the result key is"". - An empty object or array adds no keys at all.
- Keys appear in the order a depth-first walk finds them. Depth-first means you finish everything inside one key before you move to the next key. Inside each object, follow its own key order.
Don't modify the input. Keys never contain dots.
Input: squashObject({ a: 5, b: { c: 6, d: { e: 7 } } })
Output: { a: 5, 'b.c': 6, 'b.d.e': 7 }
Input: squashObject({ list: [{ id: 1 }, [2]] })
Output: { 'list.0.id': 1, 'list.1.0': 2 }
Input: squashObject({ a: { '': { b: 1 } }, x: {} })
Output: { 'a.b': 1 }the empty key is skipped and the empty object adds nothing