Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从两个类别的JavaScript数组计算总计和小计_Javascript_Arrays_Ecmascript 6_Javascript Objects - Fatal编程技术网

从两个类别的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