I am trying to flatten multi level JSON object to simple output.
key2:{
keyB1:{
keyC1:{
keyD1:'value b c 1'
}
},
keyB2:{
keyC2:'value b c 2'
}
}
My output is fine in the first iteration, but the second time, the counter is not getting set. Kindly, run the code to see the problem.
function flattenInput(datainput) {
const result = {};
const callit1 = function(keylist, datainput) {
for (i in datainput) {
keylist = keylist + '.' + i;
if (typeof datainput[i] === 'object') {
return callit1(keylist, datainput[i]);
} else {
return keylist;
}
}
}
let klist = '';
for (i in datainput) {
if (typeof datainput[i] === 'object') {
klist = callit1(i, datainput[i]);
console.log(klist);
}
}
console.log(result);
}
flattenInput(input);
Expected:
key2.keyB1.keyC1.keyD1: 'value b c 1'
key2.keyB2.keyC2: 'value b c 2'
What I get:
key2.keyB1.keyC1.keyD1: 'value b c 1' (only)
1 Answer 1
You can use recursion in order to go deeper thru the keys, and an array of keys for keeping the track of visited keys.
This is assuming the deepest object is a string.
let obj = { key2: { keyB1: { keyC1: { keyD1: 'value b c 1' } }, keyB2: { keyC2: 'value b c 2' } } };
function downstream(desiredObj, currentObj, keys) {
if (typeof currentObj === 'string') {
desiredObj[keys.join('.')] = currentObj;
} else {
Object.keys(currentObj).forEach(key => downstream(desiredObj, currentObj[key], [...keys, key]));
}
}
let result = {};
Object.keys(obj).forEach(key => downstream(result, obj[key], [key]));
console.log(result);
answered Apr 6, 2019 at 0:51
Ele
33.8k7 gold badges43 silver badges80 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
lang-js
key2.keyB1.keyB2.keyC2for the second key. You need a different variable to store the "keylist" for the actual item or docallit1(keylist + "." + i, datainput[i])instead of overriding the original value. Otherwise the code looks ok. I guess it is part of an untested spaghetti code. I would check the console for errors.