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
isObject1
check 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
compare
is in your contextYou should not define
keyval
as 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
p
the name of the property to look ato
the value of the property to look atm
the 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)];