从两个类别的JavaScript数组计算总计和小计
我试图使用从两个类别的JavaScript数组计算总计和小计,javascript,arrays,ecmascript-6,javascript-objects,Javascript,Arrays,Ecmascript 6,Javascript Objects,我试图使用Array.prototype.reduce>将三个总数相加:totalPoints,monthlyTotals,和monthlyByType 我有totalPoints,和monthlyTotals效果很好,但我被最后一个monthlyByType卡住了 下面是我需要迭代的数组: const gamePointsArray = [ { gamePlayId: 'ggg1', gameType: 1, gameMonth: 4, gamePoints
Array.prototype.reduce>将三个总数相加:totalPoints
,monthlyTotals
,和monthlyByType
我有totalPoints
,和monthlyTotals
效果很好,但我被最后一个monthlyByType
卡住了
下面是我需要迭代的数组:
const gamePointsArray = [
{
gamePlayId: 'ggg1',
gameType: 1,
gameMonth: 4,
gamePoints: 4000,
},
{
gamePlayId: 'ggg2',
gameType: 2,
gameMonth: 2,
gamePoints: 7000,
},
{
gamePlayId: 'ggg3',
gameType: 2,
gameMonth: 0,
gamePoints: 3000,
},
{
gamePlayId: 'ggg4',
gameType: 1,
gameMonth: 8,
gamePoints: 25000,
},
{
gamePlayId: 'ggg5',
gameType: 3,
gameMonth: 8,
gamePoints: 5000,
},
{
gamePlayId: 'ggg6',
gameType: 3,
gameMonth: 3,
gamePoints: 10000,
},
{
gamePlayId: 'ggg7',
gameType: 2,
gameMonth: 3,
gamePoints: 5000,
},
]
这是我的减速机:
const gamePointsReducer = (acc, game) => {
const { gamePlayId, gameType, gameMonth, gamePoints,} = game
if (!acc['totalPoints']) {
acc['totalPoints'] = gamePoints
} else {
acc['totalPoints'] += gamePoints
}
if (!acc['monthlyTotals']) {
acc['monthlyTotals'] = {
0: 0,
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0,
7: 0,
8: 0,
9: 0,
10: 0,
11: 0,
}
}
acc.monthlyTotals[`${gameMonth}`] += gamePoints
if (!acc['monthByType']) {
acc['monthByType'] = {
0: {},
1: {},
2: {},
3: {},
4: {},
5: {},
6: {},
7: {},
8: {},
9: {},
10: {},
11: {},
}
}
acc.monthByType[`${gameMonth}`] += {
[`${gameType}`]: gamePoints
}
return acc
}
const monthTotalsObj = gamePointsArray.reduce(gamePointsReducer, {})
console.log('Game Points totals obj', monthTotalsObj);
我需要最终结果对象
如下所示:
{
totalPoints: 59000,
monthlyTotals: {
0: 3000,
1: 0,
2: 7000,
3: 15000,
4: 4000,
5: 0,
6: 0,
7: 0,
8: 30000,
9: 0,
10: 0,
11: 0,
},
monthByType: {
0: {
2: 3000,
},
1: {},
2: {
2: 7000,
},
3: {},
4: {
1: 4000,
},
5: {},
6: {},
7: {},
8: {
1: 25000,
3: 5000,
},
9: {},
10: {},
11: {},
}
}
您可以创建一个默认的intialValue
对象。这将帮助您避免在整个reduce回调过程中执行if
检查
然后reduce
回调类似于您已经在做的事情。只需更新每个monthByType
const gamePoints ray=[{gamePlayId:“ggg1”,游戏类型:1,游戏月份:4,游戏点数:4000,},{gamePlayId:“ggg2”,游戏类型:2,游戏点数:7000,},{gamePlayId:“ggg3”,游戏类型:2,游戏月份:0,游戏点数:3000,},{gamePlayId:“ggg4”,游戏类型:1,游戏月份:8,游戏点数:25000,},{gamePlayId:“gggg5”,游戏类型:3,游戏月份:8,游戏点数:5000,},{gamePlayId:“ggg6”,游戏类型:3,游戏月份:3,游戏点数:10000,},{gamePlayId:“ggg7”,游戏类型:2,游戏月份:3,游戏点数:5000,}];
常量initialValue={
总积分:0,
MonthlyToals:{…数组(12).fill(0)},
monthByType:{…数组。from({length:12},{=>({}))}
}
常量输出=游戏点数组.reduce((acc,o)=>{
acc.totalPoints+=o.gamePoints;
acc.monthlyTotals[o.gameMonth]+=o.gamePoints;
acc.monthByType[o.GAMEMOUNT][o.gameType]=
(acc.monthByType[o.gameMonth][o.gameType]| | 0)+o.gamePoints;
返回acc;
},初始值)
log(输出)
您可以采用预填充数组而不是对象,并分配或添加值
constgetyear=fn=>Array.from({length:12},fn);
var data=[{gamePlayId:'ggg1',gameType:1,gameMonth:4,gamePoints:4000},{gamePlayId:'ggg2',gameMonth:2,gamePoints:7000},{gamePlayId:'ggg3',gameMonth:0,gamePoints:3000},{gamePlayId:'ggg4',gameMonth:1,gameMonth:8,gamePoints:25000,{gamePlayId:'ggg5',游戏类型:3,游戏月份:8,游戏点数:5000},{gamePlayId:'ggg6',游戏类型:3,游戏月份:3,游戏点数:10000},{gamePlayId:'ggg7',游戏类型:2,游戏月份:3,游戏点数:5000},
结果=数据.reduce((r,{gameType,gameMonth,gamePoints})=>{
r、 总+=游戏点数;
r、 monthlyTotals[gameMonth]+=游戏点数;
r、 monthByType[gameMonth][gameType]=(r.monthByType[gameMonth][gameType]| | 0)+游戏点数;
返回r;
},{total:0,monthlyTotals:getYear(()=>0),monthByType:getYear(()=>({}))};
console.log(结果);
.as console wrapper{max height:100%!important;top:0;}
一个gameType
-gameMonth
组合是否只有一个条目?例如,是否存在另一个gameType:1,gameMonth:4,
?@NinaScholz想要的结果发布在我说的地方,“我需要最终结果对象如下:“@adiga nope,在给定的一个月内,对于给定的游戏类型,该月只能有一个条目。希望这有帮助。抱歉,但我误解了。在那里,GamePointsRay可以有重复的类型和月份,结果是”monthByType““这些重复项需要一起添加。不幸的是,您的代码没有考虑到这一点。我试图进行调整,但出现了不足。@Clay\u F对此进行了更新。与其直接分配o.gamePoint
,不如检查该游戏类型是否已经有值。如果有,请使用该值,否则请使用0(acc.monthByType[o.gameMonth][o.gameType]| | 0)+o.gamePoints