繁体   English   中英

使用javascript reduce方法将对象数组转换为每年和每月

[英]convert array of objects to yearly and monthly using javascript reduce method

问题陈述 :

我有一个以月,销售和订单为属性的对象数组。 现在,我想创建一个类似下面的函数。 可以根据参数提供结果。

function aggregate(json_data , yearly)
{
  // This function could return an array of objects like following
  // [ { Month : 2014 , Sales : x , Amount : x},
  //   { Month : 2015 , Sales : x , Amount : x }
  //  ]
};

如果用户将参数传递为季度,则数据应按季度汇总

function aggregate(json_data , quarterly)
{
  // This function could return an array of objects
  // [ { Month : 2014Q1 , Sales : x , Amount : x},
  //   { Month : 2014Q2 , Sales : x , Amount : x }
  //    ............
  //    ............
  //  ]
}

样本数据

 var data = [
  {
     Month: 201401,
     Sales: 15,
     Orders: 4
  },
  {
     Month: 201402,
     Sales: 12,
     Orders: 3

  },
  {
     Month: 201403,
     Sales  : 16,
     Orders: 5

  },
  {
     Month: 201404,
     Sales: 12,
     Orders: 2
  },

  {
     Month: 201405,
     Sales: 12,
     Orders: 4
  },

  {
     Month: 201406,
     Sales: 10,
     Orders: 3
  },

  {
     Month: 201407,
     Sales: 15,
     Orders: 2
  },

  {
     Month: 201408,
     Sales: 14,
     Orders: 3
  },

  {
     Month: 201409,
     Sales: 13,
     Orders: 6
  },

  {
     Month: 201410,
     Sales: 13,
     Orders: 5
  },

  {
     Month: 201411,
     Sales: 12,
     Orders: 2
  },

  {
     Month: 201412,
     Sales: 11,
     Orders: 4
  },
  {
     Month: 201501,
     Sales: 15,
     Orders: 4
  },
  {
     Month: 201502,
     Sales: 12,
     Orders: 6

  },
  {
     Month: 201503,
     Sales  : 6,
     Orders: 5

  },
  {
     Month: 201504,
     Sales: 10,
     Orders: 11
  },

  {
     Month: 201505,
     Sales: 10,
     Orders: 2
  },

  {
     Month: 201506,
     Sales: 10,
     Orders: 3
  },

  {
     Month: 201507,
     Sales: 10,
     Orders: 1
  },

  {
     Month: 201508,
     Sales: 10,
     Orders: 4
  },

  {
     Month: 201509,
     Sales: 10,
     Orders: 2
  },

  {
     Month: 201510,
     Sales: 10,
     Orders: 3
  },

  {
     Month: 201511,
     Sales: 10,
     Orders: 2
  },

  {
     Month: 201512,
     Sales: 10,
     Orders: 1
  }
];

请提出建议,如果还有其他建议可以适应该问题。

有人建议这是一个重复的问题。 但是,我正在使用日期对象。 (建议之前请检查重复的链接)

您可以使用哈希表,并根据所需的年度或季度数据汇总使用键。

该提案使用Month作为字符串。

 function aggregate(array, quarterly) { var hash = Object.create(null), result = []; data.forEach(function (o) { var [period, month] = o.Month.toString().split(/(?=..$)/); if (quarterly) { period += 'Q' + Math.floor((+month + 2) / 3); } if (!hash[period]) { hash[period] = { period, Sales: 0, Orders: 0 }; result.push(hash[period]); } hash[period].Sales += o.Sales; hash[period].Orders += o.Orders; }); return result; } var data = [{ Month: 201401, Sales: 15, Orders: 4 }, { Month: 201402, Sales: 12, Orders: 3 }, { Month: 201403, Sales: 16, Orders: 5 }, { Month: 201404, Sales: 12, Orders: 2 }, { Month: 201405, Sales: 12, Orders: 4 }, { Month: 201406, Sales: 10, Orders: 3 }, { Month: 201407, Sales: 15, Orders: 2 }, { Month: 201408, Sales: 14, Orders: 3 }, { Month: 201409, Sales: 13, Orders: 6 }, { Month: 201410, Sales: 13, Orders: 5 }, { Month: 201411, Sales: 12, Orders: 2 }, { Month: 201412, Sales: 11, Orders: 4 }, { Month: 201501, Sales: 15, Orders: 4 }, { Month: 201502, Sales: 12, Orders: 6 }, { Month: 201503, Sales: 6, Orders: 5 }, { Month: 201504, Sales: 10, Orders: 11 }, { Month: 201505, Sales: 10, Orders: 2 }, { Month: 201506, Sales: 10, Orders: 3 }, { Month: 201507, Sales: 10, Orders: 1 }, { Month: 201508, Sales: 10, Orders: 4 }, { Month: 201509, Sales: 10, Orders: 2 }, { Month: 201510, Sales: 10, Orders: 3 }, { Month: 201511, Sales: 10, Orders: 2 }, { Month: 201512, Sales: 10, Orders: 1 }]; console.log(aggregate(data)); console.log(aggregate(data, true)); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

不能完全确定是否存在相同的问题,但是最近我不得不解决至少看起来非常相似的问题。 我有一个带有日期和值的对象数组,例如:

statsData = [
      { x: randomDate, y: 1 },
      { x: randomDate, y: 2 },
      { x: randomDate, y: 1 },
      { x: randomDate, y: 4 },
      { x: randomDate, y: 3 },
      { x: randomDate, y: 2 },
      { x: randomDate, y: 1 },
      { x: randomDate, y: 4 },
      { x: randomDate, y: 6 },
      { x: randomDate, y: 5 },
      { x: randomDate, y: 1 }
]

而且我需要减少它,以便将具有同一月份的所有对象归为一个对象,该对象将添加该月的所有值。

我要做的是,首先对它们进行排序,以防它们不按时间顺序排列:

sortData(data) {
    return data.sort((a, b) => {
      return +a.x - +b.x;
    });
}

然后使用以下reduce函数:

reduceByMonth(data) {
    if (data) {
      return data.reduce((total, current, index) => {
        const month = { x: null, y: 0 };
        if (index !== 0 && (total && total[total.length - 1] && total[total.length - 1].x && monthsMatch(total[total.length - 1].x, current.x))) {
          total[total.length - 1].y = total[total.length - 1].y + current.y;
          return total;
        } else {
          month.x = new Date(current.x.getFullYear(), current.x.getMonth());
          month.y = month.y + current.y;
          total.push(month);
          return total;
        }
      }, []);
    } else {
      console.error('Cannot reduce undefined data');
      return []
    }
  }

monthsMatch函数只是检查两个日期的月份是否匹配:

monthsMatch(dateA, dateB) {
    if (dateA.getFullYear() === dateB.getFullYear()) {
      return dateA.getMonth() === dateB.getMonth();
    } else {
      return false;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM