Home > Mobile >  Flatten and combining an Array of Objects
Flatten and combining an Array of Objects

Time:02-19

I have an array of objects like so

[
   {
      "id":1,
      "name":"Competition One",
      "entrants": [
          {
              "id":1,
              "competitionId":1,
              "duration":"3 minutes",
           },
           {
              "id":2,
              "competitionId":1,
              "duration":"2 hours",
           },
      ]
   },
   {
      "id":2,
      "name":"Competition Two",
      "entrants": [
            {
              "id":3,
              "competitionId":2,
              "duration":"5 hours",
           },
      ]
   },
]

What I am trying to do is get a flat array containing only the entrants, as such I am doing this

const entrants = competitions.flatMap((comp) => {
    return comp.entrants;
});

This seems to do the job. I now have the following

[
   {
      "id":1,
      "competitionId":1,
      "duration":"3 minutes",
   },
   {
      "id":2,
      "competitionId":1,
      "duration":"2 hours",
   },
   {
      "id":3,
      "competitionId":2,
      "duration":"5 hours",
   }
]

However, what I can't figure out is how to add a new field within the above data that contains the name of the competition. So what I am after is this

[
   {
      "id":1,
      "competitionId":1,
      "name": "Competition One"
      "duration":"3 minutes",
   },
   {
      "id":2,
      "competitionId":1,
      "name": "Competition One"
      "duration":"2 hours",
   },
   {
      "id":3,
      "competitionId":2,
      "name": "Competition Two"
      "duration":"5 hours",
   }
]

How can this be achieved? I know how to do this with conventional loops, but trying to force myself to learn the ES6 way of doing things. Is this where a reduce could come in handy?

Any advice appreciated.

Thanks

CodePudding user response:

You can use a nested map and then merge the object with the extra property:

let competitions = [{  "id":1, "name":"Competition One", "entrants": [{"id":1,"competitionId":1,"duration":"3 minutes",},{ "id":2,"competitionId":1,"duration":"2 hours",},]},{"id":2,"name":"Competition Two","entrants": [{"id":3,"competitionId":2,"duration":"5 hours",},]},]

let result = competitions.flatMap(({name, entrants}) =>
    entrants.map(entrant => ({name, ...entrant}))
);

console.log(result);

CodePudding user response:

Using Array#map to get each list of entrants with the corresponding competition name:

const competitions = [
  {
    "id":1,
    "name":"Competition One",
    "entrants": [ { "id":1, "competitionId":1, "duration":"3 minutes" }, { "id":2, "competitionId":1, "duration":"2 hours" } ]
  },
  {
    "id":2,
    "name":"Competition Two",
    "entrants": [ { "id":3, "competitionId":2, "duration":"5 hours" } ]
  }
];

const entrants = competitions.flatMap(({ name, entrants = [] }) =>
  entrants.map(entrant => ({ ...entrant, name }))
);

console.log(entrants);

CodePudding user response:

Merge the name property into comp.entrants when mapping.

const entrants = competitions.flatMap((comp) => {
    return {name: comp.name, ...comp.entrants};
});
  • Related