You can recursively visit nodes by keeping a stack reference. I modified the object by adding an example of an array.
I simply join the path with dot separators and then transform numeric keys into bracket notation using the following regular expression.
/(?:\.)(\d+)(?![a-z_])/ig
I combined a non-matching group (starts with a dot) and with a negative lookahead (does not precede a letter).
Alternatively, you can use the following expression:
/(?:\.)(\d+)(?=\.)/g
I replaced the negative lookahead with a positive lookahead. I essentially inverted the expression, which may be better for this situation.
const obj = {
nested: {
nested2: [
{ nested3: '123' },
{ nested4: '456' }
],
nested5: '789'
}
};
const visitNodes = (obj, visitor, stack = []) => {
if (typeof obj === 'object') {
for (let key in obj) {
visitNodes(obj[key], visitor, [...stack, key]);
}
} else {
visitor(stack.join('.').replace(/(?:\.)(\d+)(?![a-z_])/ig, '[$1]'), obj);
}
}
visitNodes(obj, (path, value) => console.log(`${path} = ${value}`));