Im trying to get the full path of an array of objects by using recursion to loop over the array objects and get their path with relation to the parent, what i couldn't do was the part when the path reset and starts to add the "child" key .
const data = {
data: [
{
key: 'userInfo',
group: [
{
key: 'street',
},
{
key: 'phone',
},
],
},
{
key: 'fullName',
group: [
{
key: 'firstName',
},
{
key: 'lastName',
},
],
},
],
};
// userInfo.street
// userInfo.phone
// fullName.firstName
// fullName.lastName
let groupPath = '';
data.data.forEach(function iter(a) {
if (a.group) {
groupPath = a.key;
} else {
groupPath = [groupPath, a.key].join('.');
}
Array.isArray(a.group) && a.group.forEach(iter);
console.log(' group', groupPath);
});
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
The finale result should look like this :
userInfo.street
userInfo.phone
fullName.firstName
fullName.lastName
CodePudding user response:
It seems like you can maintain an array of all the groups and just do a couple loops to get this done. The following should do it for you
const data={data:[{key:"userInfo",group:[{key:"street"},{key:"phone"}]},{key:"fullName",group:[{key:"firstName"},{key:"lastName"}]}]};
const groups = [];
data.data.forEach(el => {
if (el.group) {
el.group.forEach(group => {
groups.push(`${el.key}.${group.key}`);
})
}
})
console.log(groups);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Updated logic.
Issue with current code
You are over writing groupPath
with the child node details inside the else block of your execution.
const data={data:[{key:"userInfo",group:[{key:"street"},{key:"phone"}]},{key:"fullName",group:[{key:"firstName"},{key:"lastName"}]}]};
let groupPath = '';
let rootGroupPath = '';
let groupList = [];
data.data.forEach(function iter(a) {
if (a.group) {
rootGroupPath = a.key;
} else {
groupPath = [rootGroupPath, a.key].join('.');
groupList.push(groupPath);
}
Array.isArray(a.group) && a.group.forEach(iter);
});
console.log(' group', groupList);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Simplified approach
Use Array.flatMap
Logic
- Loop through
data.data
array. - Inside each data node in this Array, run a
Array.map
and returnkey
from outer node andkey
from group node.
Working Fiddle
const data = { data: [{ key: "userInfo", group: [{ key: "street" }, { key: "phone" }] }, { key: "fullName", group: [{ key: "firstName" }, { key: "lastName" }] }] };
const groupList = data.data.flatMap((data) => data.group.map((group) => `${data.key}.${group.key}`));
console.log(' group', groupList);
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Here is a recursion function that can get the paths with unlimited layer.
const data = {
data: [
{
key: 'userInfo',
group: [
{
key: 'street',
group:[
{
key: 'city',
group: [
{key: 'country'}
]
}
]
},
{
key: 'phone',
},
],
},
{
key: 'fullName',
group: [
{
key: 'firstName',
},
{
key: 'lastName',
},
],
},
],
};
function getPaths({key,group})
{
return Array.isArray(group) ? group.flatMap(it => getPaths(it).map(path => key != null ? `${key}.${path}` : path)) : [key];
}
const paths = getPaths({key:null,group:data.data});
console.log(paths);
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can use a forEach
method for this, instead of using a recursion.
const data = {
data: [{
key: 'userInfo',
group: [{
key: 'street',
},
{
key: 'phone',
},
],
},
{
key: 'fullName',
group: [{
key: 'firstName',
},
{
key: 'lastName',
},
],
},
],
};
let res = [];
data.data.forEach((i)=>{
let key = i.key;
i.group.forEach((j)=>{
let str = key "." j.key;
res.push(str);
});
})
console.log(res);
// userInfo.street
// userInfo.phone
// fullName.firstName
// fullName.lastName
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If you need to use recursion, you can check this snippet out.
const data = {
data: [{
key: 'userInfo',
group: [{
key: 'street',
},
{
key: 'phone',
},
],
},
{
key: 'fullName',
group: [{
key: 'firstName',
},
{
key: 'lastName',
},
],
},
],
};
let res = [];
let idx = 0;
function iter(obj) {
let key = obj.key;
if (obj.group) obj.group.forEach(i => res.push(key "." i.key))
idx ;
//base condition
if (idx == data.data.length) return;
iter(data.data[idx]);
}
iter(data.data[idx]);
console.log(res);
<iframe name="sif7" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Using flatMap
and map
in one iteration
const getPaths = (arr) =>
arr.flatMap(({ key, group }) => group.map(({ key: k }) => `${key}.${k}`));
const data = {
data: [
{
key: "userInfo",
group: [
{
key: "street",
},
{
key: "phone",
},
],
},
{
key: "fullName",
group: [
{
key: "firstName",
},
{
key: "lastName",
},
],
},
],
};
console.log(getPaths(data.data))
<iframe name="sif8" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>