使用多个值将数据分组

时间:2018-07-25 06:10:11

标签: javascript

我想根据渠道名称和日期将这些数据解析为按年和按月。如果没有特定月份或特定日期的订单,则该月份和日期的订单计数值应设置为零,

[
{
"ordersCount": 8,
"channel": "test-1",
"period": "4 Feb 2017"
},
{
"ordersCount": 4,
"channel": "test-1",
"period": "25 Feb 2017"
},
{
"ordersCount": 1,
"channel": "test-2",
"period": "24 Jan 2018"
}
]

我预期的赔率是:

[
{
"channel": "test-1",
"Data": {
  "Year": [
    {
      "period": "Jan 2017",
      "orders": 0
    },
    {
      "period": "Feb 2017",
      "totalOrders": 12
    },{
      "period": "Mar 2017",
      "totalOrders": 0
    }...
  ],
  "Month": [
    {
      "period": "Jan 1",
      "totalOrders": 0
    },
    {
      "period": "Jan 2",
      "totalOrders": 0
    }
    ]
  }
 }
 ]

这是我尝试过的: js fiddle

2 个答案:

答案 0 :(得分:0)

这是一个仅处理数年的版本(从那里可以轻松实现数月)。

注意:

  • 我将日期更改为仅考虑最近12个月 (请参阅上面的评论),如果需要可以进行调整。
  • 日期(period)采用year-month格式,也可以调整。

const input = [{
  "ordersCount": 8,
  "channel": "test-1",
  "period": "4 Feb 2018"
},
{
  "ordersCount": 4,
  "channel": "test-1",
  "period": "25 Feb 2018"
},
{
  "ordersCount": 1,
  "channel": "test-2",
  "period": "24 Jan 2018"
}];

let result = {};

const twelveMonthsAgo = new Date(); twelveMonthsAgo.setMonth(twelveMonthsAgo.getMonth() - 12);

for (let entry of input) {   
  const entryDate = new Date(entry.period);
  
  if (entryDate >= twelveMonthsAgo) {
    result[entry.channel] = result[entry.channel] || { 
      channel: entry.channel, 
      data: { year: {}, month: {} } 
    };
      
    const monthKey = entryDate.getFullYear() + '-' + (entryDate.getMonth() + 1);
    if (!result[entry.channel].data.year[monthKey]) {
      result[entry.channel].data.year[monthKey] = {
        period: monthKey,
        totalOrders: 0
      };
    }
    
    result[entry.channel].data.year[monthKey].totalOrders += entry.ordersCount;
  }
}

result = Object.keys(result).map(channel => ({ 
  channel,
  data: {
    year: Object.values(result[channel].data.year), 
    month: []
  }
}));

console.log(result);

答案 1 :(得分:0)

您可以尝试下面的代码,该代码根据年份以及当年的月份给出输出。尝试在浏览器控制台中运行它。

var incomingResponse  = [
 {
   "ordersCount": 8,
   "channel": "qoo10-SGD",
   "period": "4 Feb 2018"
 },
 {
   "ordersCount": 100,
   "channel": "qoo10-SGD",
   "period": "25 Feb 2018"
 },
 {
   "ordersCount": 12,
   "channel": "qoo10-SGD",
   "period": "25 Feb 2018"
 },
 {
   "ordersCount": 1,
   "channel": "lazada-MYR",
   "period": "24 Oct 2018"
 },
 {
   "ordersCount": 12,
   "channel": "lazada-MYR",
   "period": "25 Jun 2018"
 },
 {
   "ordersCount": 12,
   "channel": "lazada-MYR",
   "period": "4 Feb 2017"
 },
 {
   "ordersCount": 1,
   "channel": "magento-SGD",
   "period": "21 Feb 2018"
 },
 {
   "ordersCount": 3,
   "channel": "lazada-MYR",
   "period": "13 Oct 2018"
 }
];
function daysInMonth (month, year) {
    return new Date(year, month, 0).getDate();
}

var result = {};
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
$.each(incomingResponse, function(key, value){
    var inputPeriod = value.period;
    var inputPeriodDate = new  Date(inputPeriod);
    var inputPeriodDateYear = inputPeriodDate.getFullYear();
    var inputPeriodDateMonth = inputPeriodDate.getMonth();

    // initializing default values based on channel for particular year period
    if( result[value.channel] == null || typeof result[value.channel] == 'undefined' ) {
        result[value.channel] = {'channel':value.channel, 'data':{'year':[]}};
    }

    // adding list of years as keys in above created year array
    if( result[value.channel]['data']['year'][inputPeriodDateYear] == null || 
        typeof result[value.channel]['data']['year'][inputPeriodDateYear] == 'undefined' ) {
        result[value.channel]['data']['year'][inputPeriodDateYear] = [];
    }

    // checking if data is present for particular year & particular month. If not present then creating default value set
    if( result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]] == null || 
        typeof result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]] == 'undefined' ) {
        result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]] = {'period':months[inputPeriodDateMonth] +' '+ inputPeriodDateYear, 'totalOrders':0, 'month': []};

        // retrieve number of days present in a month
        var numberOfMonthDays = daysInMonth((inputPeriodDateMonth + 1), inputPeriodDateYear);
        for(var dateCntr = 1; dateCntr <= numberOfMonthDays; dateCntr++) {
            result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]]['month'].push({'period': months[inputPeriodDateMonth] +' '+ dateCntr, 'totalOrders': 0});
        }
    }

    // before coming here, we already have default values present for year & month of selected input period.
    // so just adding up existing values of orders with order value coming from selected input period.
    result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]]['totalOrders'] = result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]]['totalOrders'] + parseInt(value.ordersCount);

    result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]]['month'][inputPeriodDate.getDate() - 1]['totalOrders'] = result[value.channel]['data']['year'][inputPeriodDateYear][months[inputPeriodDateMonth]]['month'][inputPeriodDate.getDate() - 1]['totalOrders'] + parseInt(value.ordersCount);
});
console.log(result);