I'm trying to expand array in JavaScript. The object ↓
const tests = [
{
id: 1,
name: 'taro',
designs: [
{
designId: 1,
designName: "design1"
},
{
designId: 2,
designName: "design2"
}
]
},
{
id: 2,
name: 'John',
designs: [
{
designId: 3,
designName: "design3"
},
{
designId: 4,
designName: "design4"
}
]
},
{
id: 3,
name: 'Lisa',
designs: []
},
];
[
{ id: 1, name: 'taro', designId: 1, designName: 'design1' },
{ id: 1, name: 'taro', designId: 2, designName: 'design2' },
{ id: 2, name: 'John', designId: 3, designName: 'design3' },
{ id: 2, name: 'John', designId: 4, designName: 'design4' },
{ id: 3, name: 'Lisa', designId: null, designName: null },
]
It is easy to do this using double for, but I want to use it with higher-order functions.
The code I wrote
for (let i = 0; i < tests.length; i ) {
for (let j = 0; j < tests[i].designs.length; j ) {
const id = tests[i].id
const name = tests[i].name
result.push({
id,
name,
designId: tests[i].designs[j].designId,
designName: tests[i].designs[j].designName
})
}
}
In addition, it would be appreciated if you could additionally explain the difference in performance between double for and higher-order functions.
CodePudding user response:
You can use .flatMap()
on your tests array with an inner .map()
on each designs
array. The inner map on the designs array will take the properties from the currently iterated design object and merge it with the properties from the parent object. The outer .flatMap()
can then be used to concatenate all returned maps into the one array:
const tests = [ { id: 1, name: 'taro', designs: [ { designId: 1, designName: "design1" }, { designId: 2, designName: "design2" } ] }, { id: 2, name: 'John', designs: [ { designId: 3, designName: "design3" }, { designId: 4, designName: "design4" } ] }, ];
const res = tests.flatMap(({designs, ...rest}) => designs.map(design => ({
...rest,
...design
})));
console.log(res);
Edit:
If you need null
values to appear for your design objects if your designs array is empty, you can add the keys explicitly to a new object that you can return when the designs array is empty:
CodePudding user response:
You can use an Array.reduce
function with Array.map
to generate the array:
const results = tests.reduce((acc, { designs, ...rest }) => [
...acc,
...designs.map(e => ({ ...rest, ...e }))
], []);
CodePudding user response:
You can use the higher-order function Array.prototype.reduce() with Array.prototype.map()
const newArr = tests.reduce((prev, {designs, ...current}) => [
...prev, ...designs.map(design => ({...design,...current}));
]
, []);
The performance in your approach and this higher-order approach is the same because Array.prototype.reduce
runs through the whole array and just facilitates the initialValue
approach for us.