嵌套array.map()的多个级别

时间:2018-04-02 05:05:36

标签: javascript

我有javascript数组,其中包含三个对象,每个对象都有一个数组(teamLineup),另外还有两个对象(团队),每个对象都有另一个数组(starters),最后有我想要提取的对象(player.name)。三个顶级对象具有以下结构:

let game1 = { teamLineup: [{
      team: {
        actual: {
          starters: [{
            player: {name: 'Joe'},
            player: {name: 'Kim'}
          }]
        }
      }
    },{
      team: {
        actual: {
          starters: [{
            player: {name: 'John'},
            player: {name: 'Shauna'}
          }]
        }
      }
    }]
  }

(game2....game3)

我正在尝试将原始数组缩减为单个数组,只将播放器名称作为字符串。

let games = [game1, game2, game3]

let allStartingPlayers = games.map(a => a.teamLineup.map( b => b.team.actual.starters.map(c => c.player.name)))

console.log(allStartingPlayers);

示例输出:

[ [ [ 'Kim' ], [ 'Shauna' ] ],
  [ [ 'Nicole' ], [ 'Jennifer' ] ],
  [ [ 'Sandy' ], [ 'David' ] ] ]

有两个问题。首先,它只抓取每个starters数组中的第二个player.name。其次,它返回3个嵌套数组。

3 个答案:

答案 0 :(得分:1)

您只需要2 map。一个用于主数组,一个用于starters数组。

然后,您可以使用[].concat(...arr)来展平结果。

let game1 = { teamLineup: [{
    team: {
      actual: {
        starters: [
          {player: {name: 'Joe'}},
          {player: {name: 'Kim'}}
        ]
      }
    }
  },{
    team: {
      actual: {
        starters: [
          {player: {name: 'John'}},
          {player: {name: 'Shauna'}}
        ]
      }
    }
  }]
};

let game2 = { teamLineup: [{
    team: {
      actual: {
        starters: [
          {player: {name: 'Albert'}},
          {player: {name: 'Samantha'}}
        ]
      }
    }
  },{
    team: {
      actual: {
        starters: [
          {player: {name: 'Jina'}},
          {player: {name: 'Rob'}}
        ]
      }
    }
  }]
};

const games = [game1, game2];

const result = [].concat(...[].concat(...games.map(game => game.teamLineup.map(g => g.team.actual.starters.map(s => s.player.name)))));

console.log(result);

答案 1 :(得分:0)

你的JSON错了。即首发阵列。你需要将每个玩家分别作为一个对象。

关于拥有多个嵌套数组的第二个问题,您可以使用forEach()迭代对象,最后只将player.name推送到结果中。

见下文。

let game1 = { teamLineup: [{
      team: {
        actual: {
          starters: [
            {player: {name: 'Joe'}},
            {player: {name: 'Kim'}}
          ]
        }
      }
    },{
      team: {
        actual: {
          starters: [
            {player: {name: 'John'}},
            {player: {name: 'Shauna'}}
          ]
        }
      }
    }]
  };

let game2 = { teamLineup: [{
      team: {
        actual: {
          starters: [
            {player: {name: 'Joe2'}},
            {player: {name: 'Kim2'}}
          ]
        }
      }
    },{
      team: {
        actual: {
          starters: [
            {player: {name: 'John2'}},
            {player: {name: 'Shauna2'}}
          ]
        }
      }
    }]
  };

let game3 = { teamLineup: [{
      team: {
        actual: {
          starters: [
            {player: {name: 'Joe3'}},
            {player: {name: 'Kim3'}}
          ]
        }
      }
    },{
      team: {
        actual: {
          starters: [
            {player: {name: 'John3'}},
            {player: {name: 'Shauna3'}}
          ]
        }
      }
    }]
  };
  
let games = [game1, game2, game3]

let allStartingPlayers = [];

games.forEach(a => a.teamLineup.forEach( b => b.team.actual.starters.forEach(c => allStartingPlayers.push(c.player.name))))

console.log(allStartingPlayers);

答案 2 :(得分:0)

首先看起来你失去了一些花括号。在您的样本中写下

starters: [{
        player: {name: 'Joe'},
        player: {name: 'Kim'}
      }]

这意味着

starters[{player:{name: 'Kim'}}]

所以,也许,我们可以将这部分代码重写为

starters: [
       {player: {name: 'Joe'}},
       {player: {name: 'Kim'}}
        ]

然后,根据我的拙见,你可以像这样混合缩小和映射

let allStartingPlayers = games.reduce((a,v) => a.concat(v.teamLineup.reduce( (a,b) =>a.concat(b.team.actual.starters.map(c => c.player.name)),[])),[]);