【问题标题】:ES6: How do I unravel inner arrays and flatten the JSON array?ES6:如何解开内部数组并展平 JSON 数组?
【发布时间】:2019-03-29 18:02:48
【问题描述】:

假设我有以下 JSON 数组:

[
  {
    "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"
      }
    ]
  }
]

我想将 JSON 转换并展平为以下内容:

[
  {
    "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"
  }
]

我将如何使用 ES6 或 lodash 语法来做到这一点?

【问题讨论】:

    标签: javascript json ecmascript-6 lodash transformation


    【解决方案1】:

    使用简单循环(ES2015):

    const players = [];
    for (const team of teams) {
      for (const player of team.players) {
        players.push(Object.assign({team: team.team}, player));
      }
    }
    

    如果您的环境支持,您可以使用对象传播而不是 Object.assign

    Array#flatMap(将正式成为 ES2019 的一部分,或使用 lodash):

    const players = teams.flatMap(
      team => team.players.map(player => {...player, team: team.team})
    );
    

    【讨论】:

      【解决方案2】:

      Array#reduce 方法与Array#map 方法一起使用。

      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)

      【讨论】:

        【解决方案3】:

        您可以使用 lodah 的 _.flatMap() 来迭代数组并将结果展平。内部使用_.map() 迭代播放器并使用对象传播添加team

        const arr = [{"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"}]}]
        
        const result = _.flatMap(arr, ({ team, players }) => 
          _.map(players, o => ({ team, ...o }))
        )
        
        console.log(result)
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

        Array.flatMap()Array.map() 也可以这样做:

        const arr = [{"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"}]}]
        
        const result = arr.flatMap(({ team, players }) => 
          players.map(o => ({ team, ...o }))
        )
        
        console.log(result)
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

        【讨论】:

          【解决方案4】:

          const 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"
                }
              ]
            }
          ]
          
          const flatData = data.map(d => {
            const { team } = d
            const assignedPlayers = d.players.map(player => ({ team, ...player }))
            return assignedPlayers
          }).flat()
          
          console.log(flatData)

          【讨论】:

            【解决方案5】:

            使用 ES6(扩展运算符)以及 reduceconcat

            const arr = [{
                "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"
                  }
                ]
              }
            ]
            
            console.log(arr.reduce((acc, obj) => {
              return acc.concat(...obj.players.map(player => {
                return Object.assign({
                  team: obj.team
                }, player)
              }))
            }, []));

            【讨论】:

            • 为将来的访问者澄清一下:reduce 在 ES6 之前就存在了。
            【解决方案6】:

            只需使用以下代码即可完成!检查一下!

            var inputArray = [{"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"}]}]
            
            var result = [];
            inputArray.forEach(function(elem) {
              const players = elem.players;
              players.forEach(function(child) {
                const obj = {};
                obj["name"] = child.name;
                obj["position"] = child.position;
                obj["team"] = elem.team;
                result.push(obj);
              });
            });
            
            console.log(result);
            .as-console-wrapper{max-height: 100% !important; top:0px;}

            【讨论】:

              【解决方案7】:

              这是Array.reduce()Array.forEach() 组合的另一种选择:

              let input = [
                {
                  "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 output = input.reduce((acc, {team, players}) =>
              {
                  players.forEach(({name, position}) => acc.push({name, position, team}));
                  return acc;
              }, []);
              
              console.log(output);
              .as-console {background-color:black !important; color:lime;}
              .as-console-wrapper {max-height:100% !important; top:0;}

              【讨论】:

                猜你喜欢
                • 2019-11-26
                • 2022-01-25
                • 1970-01-01
                • 2021-12-21
                • 2016-12-14
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多