簡體   English   中英

從兩個類別的JavaScript數組計算總數和小計

[英]Calculate total and subtotals from JavaScript array on two categories

我正在嘗試使用Array.prototype.reduce將三個總數totalPointstotalPointsmonthlyTotalsmonthlyByType

我有totalPoints ,和monthlyTotalstotalPoints ,但是我被困在最后一個, 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); 

我需要最終結果Object看起來像這樣:

{
  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 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 initialValue = { totalPoints: 0, monthlyTotals: { ...Array(12).fill(0) }, monthByType: { ... Array.from({ length: 12 }, _ => ({})) } } const output = gamePointsArray.reduce((acc, o) => { acc.totalPoints += o.gamePoints; acc.monthlyTotals[o.gameMonth] += o.gamePoints; acc.monthByType[o.gameMonth][o.gameType] = (acc.monthByType[o.gameMonth][o.gameType] || 0) + o.gamePoints; return acc; }, initialValue) console.log(output) 

這是有關initialValue對象的一些進一步說明:

使用{ ...Array(12).fill(0) }Object.assign({}, Array(12).fill(0) )創建monthlyTotals屬性。 這將創建一個對象,該數組的索引作為鍵,而value作為鍵的值

monthByType需要填充對象文字。 您可以Array.from()使用Array.from() (您不能像上面那樣使用fill 。它將在每個索引中使用相同的靜態對象的引用,這是不希望的)

 const arrayWithZeros = Array(12).fill(0), monthlyTotals = { ...arrayWithZeros }; const arrayWithEmptyLiterals = Array.from({ length: 12 }, _ => ({}) ), monthByType = { ...arrayWithEmptyLiterals } console.log(JSON.stringify(arrayWithZeros)) console.log(JSON.stringify(monthlyTotals)) console.log(JSON.stringify(arrayWithEmptyLiterals)) console.log(JSON.stringify(monthByType)) 

您可以采用預填充數組而不是對象,然后分配或添加值。

 const getYear = fn => Array.from({ length: 12 }, fn); var data = [{ 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 }], result = data.reduce((r, { gameType, gameMonth, gamePoints }) => { r.total += gamePoints; r.monthlyTotals[gameMonth] += gamePoints; r.monthByType[gameMonth][gameType] = (r.monthByType[gameMonth][gameType] || 0) + gamePoints; return r; }, { total: 0, monthlyTotals: getYear(() => 0), monthByType: getYear(() => ({ })) }); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM