I have an array of objects with nested subarray (empoloyees), and the names of the attributes on the parent level can be voluntary (for example, company):
values = [{
company: 'DotCom',
employees: [{
name: 'John Doe',
position: 'Salesrep'
}, {
name: 'Mike Pen',
position: 'Driver'
}]
}, {
company: 'Green Tree',
employees: [{
name: 'Suzanne Fox',
position: 'Secretary'
}, {
name: 'Kelly Fun',
position: 'CEO Assistant'
}, {
name: 'Brian Bush',
position: 'CEO'
}]
}]
I need to transform it in a way that the resulting objects will not contain nested arrays:
[{
company: "DotCom",
name: "John Doe",
position: "Salesrep"
},
{
company: "DotCom",
name: "Mike Pen",
position: "Driver"
},
{
company: "Green Tree",
name: "Suzanne Fox",
position: "Secretary"
},
{
company: "Green Tree",
name: "Kelly Fun",
position: "CEO Assistant"
},
{
company: "Green Tree",
name: "Brian Bush",
position: "CEO"
}
]
This is my code:
values = [{company: 'DotCom', employees: [{name: 'John Doe', position: 'Salesrep'}, {name: 'Mike Pen', position: 'Driver'}]},{company: 'Green Tree', employees: [{name: 'Suzanne Fox', position: 'Secretary'}, {name: 'Kelly Fun', position: 'CEO Assistant'}, {name: 'Brian Bush', position: 'CEO'}]}]
const getEntries = (o) =>
Object.entries(o).flatMap(([k, v]) =>
Object(v) === v ? getEntries(v, k) : [
[k, v]
]
)
var result = []
values.map(item => [item].flatMap(x => result.push(Object.fromEntries(getEntries(x)))))
console.log(result)
And the result is (console.log(result)) giving me only the one (last) member of the nested array of employees, and not all of the employees:
[{
company: "DotCom",
name: "Mike Pen",
position: "Driver"
},
{
company: "Green Tree",
name: "Brian Bush",
position: "CEO"
}
]
What would be the best approach to modify the code so that I would get all of the employees into the result?
Here is another example of the values array:
values = [{
city: 'New York',
division: 'Main Office',
employees: [{
name: 'John Doe',
position: 'Salesrep'
}, {
name: 'Mike Pen',
position: 'Driver'
}]
},{
city: 'Tampa',
division: 'Regional Office',
employees: [{
name: 'Suzanne Fox',
position: 'Secretary'
}, {
name: 'Kelly Fun',
position: 'CEO Assistant'
}, {
name: 'Brian Bush',
position: 'CEO'
}]
}]
The expected result:
[{
city: 'New York',
division: 'Main Office',
name: 'John Doe',
position: 'Salesrep'
},
{...}]
CodePudding user response:
Do NOT use map or flatMap if you do not use the resulting array.
Here I use flatMap and spread to return a flattened map
Without names - assuming only ONE array and no other nesting
const values = [{company: 'DotCom', employees: [{name: 'John Doe', position: 'Salesrep'}, {name: 'Mike Pen', position: 'Driver'}]},{company: 'Green Tree', employees: [{name: 'Suzanne Fox', position: 'Secretary'}, {name: 'Kelly Fun', position: 'CEO Assistant'}, {name: 'Brian Bush', position: 'CEO'}]}]
const companyArr = values
.flatMap(item => {
const obj = {};
let arr = [];
Object.entries(item).forEach(([key,val]) => {
if (Array.isArray(val)) arr = val;
else obj[key] = val;
})
return arr.map(item => ({...obj,...item}))
});
console.log(companyArr)
Using the names
const values = [{company: 'DotCom', employees: [{name: 'John Doe', position: 'Salesrep'}, {name: 'Mike Pen', position: 'Driver'}]},{company: 'Green Tree', employees: [{name: 'Suzanne Fox', position: 'Secretary'}, {name: 'Kelly Fun', position: 'CEO Assistant'}, {name: 'Brian Bush', position: 'CEO'}]}]
const empArr = values
.flatMap(entry => entry.employees
.map(emp => ({"company": entry.company, ...emp}))
);
console.log(empArr)
CodePudding user response:
Please check if this would work for you. I am spreading the employee object and flattening the resultant array:
let values = [{
company: 'DotCom',
employees: [{
name: 'John Doe',
position: 'Salesrep'
}, {
name: 'Mike Pen',
position: 'Driver'
}]
}, {
company: 'Green Tree',
employees: [{
name: 'Suzanne Fox',
position: 'Secretary'
}, {
name: 'Kelly Fun',
position: 'CEO Assistant'
}, {
name: 'Brian Bush',
position: 'CEO'
}]
}];
let newValues = values.map(c => c.employees.map(e => {
return {
company: c.company,
...e
}
})).flatMap(x => x);
console.log(newValues);