在javascript中同时映射和减少数组

在javascript中同时映射和减少数组,javascript,arrays,mapreduce,reduce,Javascript,Arrays,Mapreduce,Reduce,我有一个约1800个对象的数组,代表在一个联盟中进行的游戏。我需要一个新数组,每个团队都有一个对象,它将包括4个新字段(赢,输,结,和分)。以下是我正在使用的阵列示例: [ { "homeGoals": 2, "gameId": "12221", "homeTeam": { "id": "aasfdsf1", "teamName": "Team 1" }, "awayTeam": { "id": "aasfdsf2"

我有一个约1800个对象的数组,代表在一个联盟中进行的游戏。我需要一个新数组,每个团队都有一个对象,它将包括4个新字段(
,和
)。以下是我正在使用的阵列示例:

[
  {
    "homeGoals": 2,
    "gameId": "12221",
    "homeTeam": {
      "id": "aasfdsf1",
      "teamName": "Team 1"
    },
    "awayTeam": {
      "id": "aasfdsf2",
      "teamName": "Team 2"
    },
    "id": "ggaew1",
    "awayGoals": 4
  },
  {
    "homeGoals": 5,
    "gameId": "12222",
    "homeTeam": {
      "id": "aasfdsf1",
      "teamName": "Team 1"
    },
    "awayTeam": {
      "id": "aasfdsf3",
      "teamName": "Team 3"
    },
    "id": "ggaew2",
    "awayGoals": 1
  },
  {
    "homeGoals": 4,
    "gameId": "12223",
    "homeTeam": {
      "id": "aasfdsf2",
      "teamName": "Team 2"
    },
    "awayTeam": {
      "id": "aasfdsf3",
      "teamName": "Team 3"
    },
    "id": "ggaew3",
    "awayGoals": 4
  },
  {
    "homeGoals": null,
    "gameId": "12223",
    "homeTeam": {
      "id": "aasfdsf2",
      "teamName": "Team 2"
    },
    "awayTeam": {
      "id": "aasfdsf3",
      "teamName": "Team 3"
    },
    "id": "ggaew4",
    "awayGoals": null
  }
]
下面是一个我需要的结果的示例:

 [
  {
    "id": "aasfdsf1",
    "name": "Team 1",
    "wins": 1,
    "losses": 1,
    "ties": 0,
    "points": 2 
  },
  {
    "id": "aasfdsf2",
    "name": "Team 2",
    "wins": 1,
    "losses": 0,
    "ties": 1,
    "points": 3 
  },
  {
    "id": "aasfdsf3",
    "name": "Team 3",
    "wins": 0,
    "losses": 1,
    "ties": 1,
    "points": 1 
  }
]
有些游戏尚未玩,因此
homegools
awayGoals
字段将为空

到目前为止,我有一个独特的球队名单,只有在比赛已经完成的地方:

const completedGames = games.filter(x => x.homeGoals !== null)
const homeTeams = [...new Set(completedGames.map(x => x['homeTeam']))];
const awayTeams = [...new Set(completedGames.map(x => x['awayTeam']))];
const teams = [...new Set([...homeTeams, ...awayTeams])]

我知道我需要做一些reduce函数,但是我在计算它时遇到了困难。我非常确信,如果我有一个适当的map reduce函数,我刚才做的步骤将是不相关的。任何帮助都将不胜感激

我想你正在寻找这样的东西:

const hashMapTeams = games.filter(x => x.homeGoals !== null)
.reduce((res, match)=>{
   /* do the calculations here */
   /* put the values on the res object, using res as a HashMap*/
    res["/*the home team id*/"].id = /*id value*/
    res["/*the home team id*/"].name = /*name value*/
    res["/*the home team id*/"].wins= /* the right value */;
    res["/*the home team id*/"].losses= /* the right value */;
    res["/*the home team id*/"].ties= /* the right value */;
    res["/*the home team id*/"].points= /* the right value */;

    res["/*the away team id*/"].id = /*id value*/
    res["/*the away team id*/"].name = /*name value*/
    res["/*the away team id*/"].wins= /* the right value */;
    res["/*the away team id*/"].losses= /* the right value */;
    res["/*the away team id*/"].ties= /* the right value */;
    res["/*the away team id*/"].points= /* the right value */;
 },{});

/* This will convert again the object to an array */
const arrayTeams = Object.keys(hashMapTeams).map(function (key) { return hashMapTeams[key]; });

我想你正在寻找这样的东西:

const hashMapTeams = games.filter(x => x.homeGoals !== null)
.reduce((res, match)=>{
   /* do the calculations here */
   /* put the values on the res object, using res as a HashMap*/
    res["/*the home team id*/"].id = /*id value*/
    res["/*the home team id*/"].name = /*name value*/
    res["/*the home team id*/"].wins= /* the right value */;
    res["/*the home team id*/"].losses= /* the right value */;
    res["/*the home team id*/"].ties= /* the right value */;
    res["/*the home team id*/"].points= /* the right value */;

    res["/*the away team id*/"].id = /*id value*/
    res["/*the away team id*/"].name = /*name value*/
    res["/*the away team id*/"].wins= /* the right value */;
    res["/*the away team id*/"].losses= /* the right value */;
    res["/*the away team id*/"].ties= /* the right value */;
    res["/*the away team id*/"].points= /* the right value */;
 },{});

/* This will convert again the object to an array */
const arrayTeams = Object.keys(hashMapTeams).map(function (key) { return hashMapTeams[key]; });

这可以用
flatMap
以更简单的方式表示。它不是内置在JS中,但易于实现:

let flatMap = (a, fn) => [].concat(...a.map(fn));
现在,在地图步骤中,您可以在每场游戏中发射两个“结果”对象(如果游戏不完整,则根本没有结果):

这很容易减少:

summary = results.reduce((m, {id, r}) => {
    let e = m[id] || {};
    e[r] = (e[r] || 0) + 1;
    return Object.assign(m, {[id]: e})
}, {});
您还可以通过将赢、输和平局分别编码为1、-1、0来减少冗余,在这种情况下,映射器将变为:

results = flatMap(
    data.filter(g => g.homeGoals !== null),
    g => {
        let d = g.homeGoals - g.awayGoals;
        return [
            {id: g.homeTeam.id, r: Math.sign(+d)},
            {id: g.awayTeam.id, r: Math.sign(-d)},
        ]
    });

这可以用
flatMap
以更简单的方式表示。它不是内置在JS中,但易于实现:

let flatMap = (a, fn) => [].concat(...a.map(fn));
现在,在地图步骤中,您可以在每场游戏中发射两个“结果”对象(如果游戏不完整,则根本没有结果):

这很容易减少:

summary = results.reduce((m, {id, r}) => {
    let e = m[id] || {};
    e[r] = (e[r] || 0) + 1;
    return Object.assign(m, {[id]: e})
}, {});
您还可以通过将赢、输和平局分别编码为1、-1、0来减少冗余,在这种情况下,映射器将变为:

results = flatMap(
    data.filter(g => g.homeGoals !== null),
    g => {
        let d = g.homeGoals - g.awayGoals;
        return [
            {id: g.homeTeam.id, r: Math.sign(+d)},
            {id: g.awayTeam.id, r: Math.sign(-d)},
        ]
    });

这将获得您想要的确切结果:

{
  "id": "aasfdsf1",
  "name": "Team 1",
  "wins": 1,
  "losses": 1,
  "ties": 0,
  "points": 2 
},
我用十进制和括号向你们展示了不止一种方法,你们可以用任何一种

let result = [];

your1800ArrayObj.map(data => {      
    let wins = data.wins ? data.wins : 0;
    let losses = data.losses ? data.losses : 0;
    let ties = data['ties'] || 0;
    let points = data['points'] || 0;

    if (data.homeGoals === null && data.awayGoals === null) {
        console.log('game not played')
        } else {
            if (data.homeGoals > data.awayGoals) {
                wins += 1
                points += 1
            } else if (data.homeGoals < data.awayGoals) {
                losses += 1
            } else {
                ties += 1
            }
        }

    result.push({
        id: data.id,
        name: data.homeTeam.teamName ,
        wins: wins,
        losses: losses,
        ties: ties,
        points: points
    })
})

return result
}
let result=[];
your1800ArrayObj.map(数据=>{
让wins=data.wins?data.wins:0;
让损失=data.loss?data.loss:0;
设ties=data['ties']|0;
设点=数据[“点”]| | 0;
if(data.homegools==null&&data.awayGoals==null){
console.log('未玩游戏')
}否则{
if(data.homeGoals>data.awayGoals){
wins+=1
点数+=1
}else if(data.homegals
这会得到您想要的准确结果:

{
  "id": "aasfdsf1",
  "name": "Team 1",
  "wins": 1,
  "losses": 1,
  "ties": 0,
  "points": 2 
},
我用十进制和括号向你们展示了不止一种方法,你们可以用任何一种

let result = [];

your1800ArrayObj.map(data => {      
    let wins = data.wins ? data.wins : 0;
    let losses = data.losses ? data.losses : 0;
    let ties = data['ties'] || 0;
    let points = data['points'] || 0;

    if (data.homeGoals === null && data.awayGoals === null) {
        console.log('game not played')
        } else {
            if (data.homeGoals > data.awayGoals) {
                wins += 1
                points += 1
            } else if (data.homeGoals < data.awayGoals) {
                losses += 1
            } else {
                ties += 1
            }
        }

    result.push({
        id: data.id,
        name: data.homeTeam.teamName ,
        wins: wins,
        losses: losses,
        ties: ties,
        points: points
    })
})

return result
}
let result=[];
your1800ArrayObj.map(数据=>{
让wins=data.wins?data.wins:0;
让损失=data.loss?data.loss:0;
设ties=data['ties']|0;
设点=数据[“点”]| | 0;
if(data.homegools==null&&data.awayGoals==null){
console.log('未玩游戏')
}否则{
if(data.homeGoals>data.awayGoals){
wins+=1
点数+=1
}else if(data.homegals
谢谢您的帮助!summary函数返回一个对象的对象,如何使其成为数组?我尝试将函数末尾的
{}
更改为
[]
,但返回了一个空白数组。感谢您的帮助!summary函数返回一个对象的对象,如何使其成为数组?我尝试将函数末尾的
{}
更改为
[]
,但返回了一个空白数组。