简体   繁体   中英

add array of object into array of object using forEach es6

I have this set of colors array ["#c4b18f", "#100f5c"]

and I want to add to each cameras, but the cameras is a nested array, like so

[
  {
    "id": 1,
    "date": "Sat",
    "cameras": [
      {
        "name": "East Gate",
        "total_count": 233
      },
      {
        "name": "South Gate",
        "total_count": 2599
      }
    ]
  },
  {
    "id": 2,
    "date": "Sun",
    "cameras": [
      {
        "name": "East Gate",
        "total_count": 123342
      },
      {
        "name": "South Gate",
        "total_count": 2333
      }
    ]
  }
]

I've tried but I got undefined

const result = data.forEach(obj => ({
                ...obj,
                cameras: obj.cameras.map((obj2, i) => ({
                    ...obj2,
                    color: colors[i]
                }))
            }))

I suspect I forgot to return something, or I should use map instead of forEach for the first loop?

Array.map

You can use Array.map() to iterate each element and return a new array.

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

In the example below, we are calling map() twice . Once for the array of objects (days) and then each time we find a cameras array.

let addColors = (days, colors) => days.map(o => {
  o.cameras = o.cameras.map( (c, i) => {
    c.colors = colors[i%colors.length];
    return c;
  });
  return o;
});

what if I have 3 color or more, will this solution work?

It will work by changing this line c.colors = colors[i%colors.length]; It uses the Remainder (%) operator. For each camera, it divides the index by the number of colors and uses the remainder as the index for the color array.

This is a little difficult to explain.

Cameras looks like this:

 "cameras": [{
    "name": "East Gate",
    "total_count": 123342
  },
  {
    "name": "South Gate",
    "total_count": 2333
  }
]

East Gate cameras has an index of 0 and South Gate cameras has an index of 1 . So we divide 0 by the number of colors (I changed the example so we have 7 cameras). It goes into 0, 0 times with no remainder. So we choose colors[0] which is red . Next, we divide 1 by 7. It goes into 1, 0 times and has a remainder of 1. So we choose colors[1] which is orange . This could continue for each set of cameras. If the number of cameras was longer than the number of colors, then the color choices would start to repeat.

I expanded the example below to show what happens when you have more cameras than colors.

Runnable Example

 let colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]; let foo = [{ "id": 1, "date": "Sat", "cameras": [{ "name": "East Gate", "total_count": 233 }, { "name": "South Gate", "total_count": 2599 } ] }, { "id": 2, "date": "Sun", "cameras": [{ "name": "East Gate", "total_count": 123342 }, { "name": "South Gate", "total_count": 2333 }, { "name": "North Gate", "total_count": 2234 }, { "name": "West Gate", "total_count": 2234 }, { "name": "North West Gate", "total_count": 2234 }, { "name": "North East Gate", "total_count": 2234 }, { "name": "South West Gate", "total_count": 2234 }, { "name": "South East Gate", "total_count": 2234 } ] } ]; let addColors = (days, colors) => days.map(o => { o.cameras = o.cameras.map( (c, i) => { c.colors = colors[i%colors.length]; return c; }); return o; }); document.querySelector('pre').innerHTML = JSON.stringify(addColors(foo, colors), null, 2); 
 <pre></pre> 

You can simply use for loop. The code below will help. Let arr be the initial array.

    for(var j=0;j<2;j++){
        var cameras = arr[j]["cameras"];
        for(var i=0;i<2;i++){
            cameras[i]["color"]=["#c4b18f", "#100f5c"]
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM