Search code examples
javascriptjsonecmascript-6lodashtransformation

ES6: How do I unravel inner arrays and flatten the JSON array?


Imagine that I have the following JSON array:

[
  {
    "team": "Colts",
    "players": [
      {
        "name": "Andrew Luck",
        "position": "quarterback"
      },
      {
        "name": "Quenton Nelson",
        "position": "guard"
      }
    ]
  },
  {
    "team": "Patriots",
    "players": [
      {
        "name": "Tom Brady",
        "position": "quarterback"
      },
      {
        "name": "Shaq Mason",
        "position": "guard"
      }
    ]
  }
]

And I want to transform and flatten the JSON to be the following:

[
  {
    "name": "Andrew Luck",
    "position": "quarterback",
    "team": "Colts"
  },
  {
    "name": "Quenton Nelson",
    "position": "guard",
    "team": "Colts"
  },
  {
    "name": "Tom Brady",
    "position": "quarterback",
    "team": "Patriots"
  },
  {
    "name": "Shaq Mason",
    "position": "guard",
    "team": "Patriots"
  }
]

How would I do this with either ES6 or lodash syntax?


Solution

  • Use Array#reduce method along with Array#map method.

    let res = data.reduce((arr, { team, players }) => arr.concat(players.map( obj => ({...obj, team }))), []);
    
    // or
    let res = data.reduce((arr, { team, players }) => [...arr, ...players.map( obj => ({...obj, team }))], []);
    
    // or
    let res = data.reduce((arr, { team, players }) => (arr.push(...players.map( obj => ({...obj, team }))),arr), []);
    

    var data = [{
        "team": "Colts",
        "players": [{
            "name": "Andrew Luck",
            "position": "quarterback"
          },
          {
            "name": "Quenton Nelson",
            "position": "guard"
          }
        ]
      },
      {
        "team": "Patriots",
        "players": [{
            "name": "Tom Brady",
            "position": "quarterback"
          },
          {
            "name": "Shaq Mason",
            "position": "guard"
          }
        ]
      }
    ]
    
    let res = data.reduce((arr, {
      team,
      players
    }) => arr.concat(players.map(obj => ({ ...obj,
      team
    }))), []);
    
    
    // or
    let res1 = data.reduce((arr, {
      team,
      players
    }) => [...arr, ...players.map(obj => ({ ...obj,
      team
    }))], []);
    
    // or
    let res2 = data.reduce((arr, {
      team,
      players
    }) => (arr.push(...players.map(obj => ({ ...obj,
      team
    }))), arr), []);
    
    
    console.log(res, res1, res2)