我有一个~1800对象的数组表示在联盟中玩的游戏。我需要一个包含每个团队对象的新数组,并且将包含4个新字段(wins
,losses
,ties
和points
)。以下是我正在使用的数组的示例:
[
{
"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
}
]
有些游戏尚未播放,因此homeGoals
和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])]
我知道我需要做一些减少功能,但我很难搞清楚它。我很确定如果我有一个合适的map reduce功能,我之前做的步骤将无关紧要。任何帮助将不胜感激!
答案 0 :(得分:2)
这可以用flatMap
以更简单的方式表达。它不是内置在JS中,但易于实现:
let flatMap = (a, fn) => [].concat(...a.map(fn));
现在,在地图步骤中,您可以发出两个"结果"每场比赛的对象(如果比赛不完整则根本没有结果):
results = flatMap(data, g => {
if (g.homeGoals === null || g.awayGoals === null)
return [];
if (g.homeGoals > g.awayGoals)
return [
{id: g.homeTeam.id, r: 'win'},
{id: g.awayTeam.id, r: 'loss'},
];
if (g.homeGoals < g.awayGoals)
return [
{id: g.homeTeam.id, r: 'loss'},
{id: g.awayTeam.id, r: 'win'},
];
if (g.homeGoals === g.awayGoals)
return [
{id: g.homeTeam.id, r: 'tie'},
{id: g.awayTeam.id, r: 'tie'},
];
});
这会创建一个类似
的数组{ id: 'aasfdsf1', r: 'loss' },
{ id: 'aasfdsf2', r: 'win' },
{ id: 'aasfdsf1', r: 'win' }, etc
很容易减少:
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)},
]
});
答案 1 :(得分:1)
我认为你正在寻找这样的事情:
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]; });
答案 2 :(得分:0)
这会得到您正在寻找的确切结果:
{
"id": "aasfdsf1",
"name": "Team 1",
"wins": 1,
"losses": 1,
"ties": 0,
"points": 2
},
我用tenary和括号向你展示了不止一种方法,你可以使用其中任何一种。
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
}