按周数或数月进行统计和分组

时间:2017-11-17 08:40:04

标签: javascript node.js momentjs

我有一个像这样的对象数组:

[ { date: '2017-11-17', count: 2 }, { date: '2017-11-16', count: 24 }, { date: '2017-11-15', count: 42 }, { date: '2017-11-14', count: 23 }, { date: '2017-11-13', count: 33 }, { date: '2017-11-12', count: 22 }, { date: '2017-11-11', count: 11 }, { date: '2017-10-04', count: 66 } ]

仅使用momentJS库和纯javascript(没有lodash _groupBy等),我如何对结果进行分组并将'count'加在一起如下:

周分组:(周一是周开始)

[ { date: '2017-11-13', count: 104 }, { date: '2017-11-06', count: 22 }, { date: '2017-10-02', count: 66 } ]

月份分组:(月份的第1个月是月初)

[ { date: '2017-11-01', count: 26 }, { date: '2017-10-01', count: 66 } ]

谢谢。

4 个答案:

答案 0 :(得分:1)

这是我写的一个函数。您将数组作为第一个参数传递给它,将'week'或'month'作为第二个参数传递给它。

function groupBy(elements, duration) {
  const formatted = elements.map(elem => {
    return { date: moment(elem.date).startOf(duration).format('YYYY-MM-DD'), count: elem.count }
  })

  const dates = formatted.map(elem => elem.date)
  const uniqueDates = dates.filter((date, index) => dates.indexOf(date) === index)

  return uniqueDates.map(date => {
    const count = formatted.filter(elem => elem.date === date).reduce((count, elem) => count + elem.count, 0)
    return { date, count }
  })
}

答案 1 :(得分:0)

以下代码组按周计算。每月获得灵感:

var datas = [ { date: '2017-11-17', count: 2 }, { date: '2017-11-16', count: 24 }, { date: '2017-11-15', count: 42 }, { date: '2017-11-14', count: 23 }, { date: '2017-11-13', count: 33 }, { date: '2017-11-12', count: 22 }, { date: '2017-11-11', count: 11 }, { date: '2017-10-04', count: 66 } ];
var groupedByWeek = datas.reduce((m, o) => {
    var monday = getMonday(new Date(o.date));
    var mondayYMD = monday.toISOString().slice(0,10);
    var found = m.find(e => e.date === mondayYMD);
    if (found) {
        found.count += o.count;
    } else {
        o.date = mondayYMD;
        m.push(o);
    }
    return m;
}, []);

console.log(groupedByWeek);

function getMonday(d) {
    var day = d.getDay();
    var diff = d.getDate() - day + (day === 0 ? -6 : 1);  
    return new Date(d.setDate(diff));
}

答案 2 :(得分:0)

您可以使用一个函数进行分组,使用单个分组的回调(此处为月份),并使用哈希表来保留相同的组。



function groupBy(array, groupFn) {
    var hash = Object.create(null),
        result = [];

    array.forEach(function (o) {
        var key = groupFn(o);
        if (!hash[key]) {
            hash[key] = { date: key, count: 0 };
            result.push(hash[key]);
        }
        hash[key].count += o.count;
    });
    return result;
}

var data = [{ date: '2017-11-17', count: 2 }, { date: '2017-11-16', count: 24 }, { date: '2017-11-15', count: 42 }, { date: '2017-11-14', count: 23 }, { date: '2017-11-13', count: 33 }, { date: '2017-11-12', count: 22 }, { date: '2017-11-11', count: 11 }, { date: '2017-10-04', count: 66 }],
    month = function (o) { return o.date.slice(0, 7) + '-01'; },
    week = function (o) {
        var d = new Date(o.date),
            day = 1000 * 60 * 60 * 24,
            offset = 4 * day;

        d.setTime(Math.floor((d.valueOf() - offset) / 7 / day) * 7 * day + offset);
        return d.toISOString().slice(0, 10);
    };

console.log(groupBy(data, month));
console.log(groupBy(data, week));

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 3 :(得分:0)

您可以使用array#reduce使用对象查找将数据阵列分组为月份和星期组。

const data = [ { date: '2017-11-17', count: 2 }, { date: '2017-11-16', count: 24 }, { date: '2017-11-15', count: 42 }, { date: '2017-11-14', count: 23 }, { date: '2017-11-13', count: 33 }, { date: '2017-11-12', count: 22 }, { date: '2017-11-11', count: 11 }, { date: '2017-10-04', count: 66 } ];

var sortedByMonth = data.reduce((res, {date, count}) => {
  let [year, month, day] = date.split('-');
  res[month] ? res[month].count += count : res[month] = { date : year+'-'+month+'-'+'01', count};
  return res;
},{});

console.log(Object.values(sortedByMonth));

var sortedByWeek = data.reduce((res, {date, count}) => {
  var startOfWeek = moment(date, 'YYYY-MM-DD').startOf('week').add(1,'days');
  res[startOfWeek] ? res[startOfWeek].count += count : res[startOfWeek] = {date: moment(startOfWeek).format('YYYY-MM-DD'), count};
  return res;
},{});
console.log(Object.values(sortedByWeek));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js"></script>