I want to iterate through nested Object and I want to store the all the child keys as separate array and return it as a Object(parent key as key and child keys as value).
let a = {
b: {
f: {
g: "hi",
i: "wow"
},
e: "hello"
},
c: {
j: "ola"
},
d: {
k: ["bonjour","salam"]
}
}
And I am expecting object like this.
{
a:[b,c,d],
b:[f,e],
f:[g,i],
c:[j],
d:[k]
}
I tried and got result to some extent.
let res = {};
let keyVal;
var isObject1: any = val => {
if (typeof val === 'object' && val)
res[keyVal] = Object.keys(val);
}
function retrieveObj(obj1) {
for (const key in obj1) {
const value1: any = obj1[key];
keyVal = key;
if (isObject1(value1))
retrieveObj(value1)
}
}
res['a'] = Object.keys(a);
retrieveObj(a);
Below is the output which I got.
{
a: [ 'b', 'c', 'd' ],
b: [ 'f', 'e' ],
c: [ 'j' ],
d: [ 'k' ]
}
can any one help me to get complete output. Thanks in advance
CodePudding user response:
You have a few problems with your code
your
isObject1check on whether something is an object or not, is not working correctly, becausetypeof [1,2,3] == 'object'will returntrue. You need an additional check for!Array.isArray(val)You are handling only the first level. You need a recursive call for nested objects.
Not sure what
compareis in your contextYou should not define
keyvalas a global variable. If you need to pass values from one scope to another, use parameters, not global variables.
The following should work
let a = {
b: {
f: {
g: "hi",
i: "wow"
},
e: "hello"
},
c: {
j: "ola"
},
d: {
k: ["bonjour","salam"]
}
}
function getAllKeys(p, o, m) {
if (!o || typeof o !== "object" || Array.isArray(o))
return m;
m[p] = Object.keys(o);
for (let k of m[p])
getAllKeys(k, o[k], m)
return m;
}
let m = getAllKeys("a", a, {})
console.log(m)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
How does it work
The function getAllKeys accepts as parameters
pthe name of the property to look atothe value of the property to look atmthe result object where all the arrays are merged into
First, if the o which is passed in, is not a "real" object we just return because we don't need to do anything on arrays or primitive types. As typeof [...] and typeof null also return 'object' we need the two additional checks ...
Next we add all keys of the current object o to the result object under a key of p (ie the name of the object we are currently looking at)
And then we check all keys of o recursively. Ie, we pass the key k and value o[k] togehter with the result object m recursively into getAllKeys.
The final return m is just for convinience, so that we don't need to define the resultobject prior to the first call of getAllKeys. Without this return m we would need to call this as follows
let m = {};
getAllKeys("a", a, m);
I don't know what you would expect from an object like the following
let a = {
b: {
c: {
d: 3
}
},
e: {
c: {
f: 4
}
}
}
The current approach will only return c: ['f']. If you want c: ['d', 'f'], you would need the following
m[p] = [ ...(m[p] || []), ...Object.keys(o)];
