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

使用javascript reduce方法将对象数组转换为年度和月度,javascript,arrays,reduce,Javascript,Arrays,Reduce,问题陈述: 我有一个以月、销售额和订单为属性的对象数组。现在,我想创建一个如下所示的函数。它可以提供基于参数的结果 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 ,

问题陈述:

我有一个以月、销售额和订单为属性的对象数组。现在,我想创建一个如下所示的函数。它可以提供基于参数的结果

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
  }
];
如果有任何其他建议,请提供建议,以适应该问题


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

您可以使用哈希表,并根据所需的年度或季度数据聚合使用密钥

此提案使用
作为字符串

函数聚合(数组,季度){
var hash=Object.create(null),
结果=[];
data.forEach(函数(o){
var[期间,月份]=o.month.toString().split(/(?=..$)/);
若有(每季度){
期间+=‘Q’+数学下限((+月+2)/3);
}
if(!散列[period]){
hash[period]={期间,销售:0,订单:0};
push(hash[period]);
}
散列[期间]。销售额+=o.销售额;
散列[period]。订单+=o.订单;
});
返回结果;
}
var数据=[{月:201401,销售额:15,订单:4},{月:201402,销售额:12,订单:3},{月:201403,销售额:16,订单:5},{月:201404,销售额:12,订单:2},{月:201405,销售额:12,订单:4},{月:201406,销售额:10,订单:3},{月:201407,销售额:15,订单:2},{月:201408,销售额:14,订单:3},{月份:201409,销售额:13,订单:6},{月份:201410,销售额:13,订单:5},{月份:201411,销售额:12,订单:2},{月份:201412,销售额:11,订单:4},{月份:201501,销售额:15,订单:4},{月份:201502,销售额:12,订单:6},{月份:201503,销售额:6,订单:5},{月份:201504,销售额:10,订单:11},{月份:201505,销售额:10,订单:2},{月份:201506,销售额:10,订单:3},{月份:201507,销售额:10,订单:1},{月份:201508,销售额:10,订单:4},{月份:201509,销售额:10,订单:2},{月份:201510,销售额:10,订单:3},{月份:201511,销售额:10,订单:2},{月份:201512,销售额:10,订单:1});
console.log(聚合(数据));
console.log(聚合(数据,true));

。作为控制台包装{max height:100%!important;top:0;}
您可以使用哈希表,并基于所需的年度或季度数据聚合使用键

此提案使用
作为字符串

函数聚合(数组,季度){
var hash=Object.create(null),
结果=[];
data.forEach(函数(o){
var[期间,月份]=o.month.toString().split(/(?=..$)/);
若有(每季度){
期间+=‘Q’+数学下限((+月+2)/3);
}
if(!散列[period]){
hash[period]={期间,销售:0,订单:0};
push(hash[period]);
}
散列[期间]。销售额+=o.销售额;
散列[period]。订单+=o.订单;
});
返回结果;
}
var数据=[{月:201401,销售额:15,订单:4},{月:201402,销售额:12,订单:3},{月:201403,销售额:16,订单:5},{月:201404,销售额:12,订单:2},{月:201405,销售额:12,订单:4},{月:201406,销售额:10,订单:3},{月:201407,销售额:15,订单:2},{月:201408,销售额:14,订单:3},{月份:201409,销售额:13,订单:6},{月份:201410,销售额:13,订单:5},{月份:201411,销售额:12,订单:2},{月份:201412,销售额:11,订单:4},{月份:201501,销售额:15,订单:4},{月份:201502,销售额:12,订单:6},{月份:201503,销售额:6,订单:5},{月份:201504,销售额:10,订单:11},{月份:201505,销售额:10,订单:2},{月份:201506,销售额:10,订单:3},{月份:201507,销售额:10,订单:1},{月份:201508,销售额:10,订单:4},{月份:201509,销售额:10,订单:2},{月份:201510,销售额:10,订单:3},{月份:201511,销售额:10,订单:2},{月份:201512,销售额:10,订单:1});
console.log(聚合(数据));
console.log(聚合(数据,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;
    }
}

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

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;
    }
}

什么是
年度
季度
?为什么你需要它是一个单一的函数,而不是两个独立的函数
聚合早期
聚合早期
?你自己尝试过什么吗?除了写问题陈述,你没有投入任何精力研究或尝试可能的解决方案虽然这不是堆栈溢出的正式要求,但它被大力鼓励,因为它降低了发生错误的可能性