Home > Back-end >  How to expand an object in an array in JavaScirpt
How to expand an object in an array in JavaScirpt

Time:09-27

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.

  • Related