https://github.com/30-seconds/30-seconds-of-code/issues/1175
const unflattenObject = obj =>
Object.keys(obj).reduce((acc, k) => {
if (k.indexOf('.') !== -1) {
const keys = k.split('.');
Object.assign(
acc,
JSON.parse(
'{' +
keys.map((v, i) => (i !== keys.length - 1 ? `"${v}":{` : `"${v}":`)).join('') +
obj[k] +
'}'.repeat(keys.length)
)
);
} else acc[k] = obj[k];
return acc;
}, {});
// TESTING
const assert = (name, fn, arg, result) => {
if (!result) {
throw new Error('result to check against is missing');
}
try {
const t = fn(arg);
if (JSON.stringify(t) !== JSON.stringify(result)) {
throw new Error(`expected ${JSON.stringify(t)} to equal ${JSON.stringify(result)}`);
}
console.log(name + ' passed');
} catch (error) {
console.error(name + ' failed', error);
}
}
const DATE = new Date('2020-08-01');
// works fine
assert('1', unflattenObject, { 'a.b.c': 1, d: 1 }, { a: { b: { c: 1 } }, d: 1 });
// is missing `a.b` because `a.c` overwrites `a`
assert('2', unflattenObject, { 'a.b': 1, 'a.c': 2, d: 3 }, { a: { b: 1, c: 2 }, d: 3 });
// fails with `Unexpected token o in JSON`
assert('3', unflattenObject, { 'a.b': 'foo', d: 3 }, { a: { b: 'foo' }, d: 3 });
// fails with `Unexpected token S in JSON`
assert('4', unflattenObject, { 'a.b': DATE, d: 3 }, { a: { b: DATE }, d: 3 });