【问题标题】:Do a count and group by weeks or months按周或月进行计数和分组
【发布时间】:2017-11-17 08:40:04
【问题描述】:

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

[ { 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 等),我如何将结果分组并将“计数”加在一起,如下所示:

周分组:(星期一是一周的开始)

[ { 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 } ]

谢谢。

【问题讨论】:

标签: javascript node.js momentjs


【解决方案1】:

以下代码按周分组。按月分组:

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】:

    这是我写的一个函数。您将数组作为第一个参数传递,将“周”或“月”作为第二个参数传递。

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

    【讨论】:

      【解决方案3】:

      您可以使用分组函数和单个分组的回调(这里是月份),并使用哈希表来保持相同的组。

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

      【讨论】:

        【解决方案4】:

        您可以使用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>

        【讨论】:

          猜你喜欢
          • 2015-02-06
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 2019-05-10
          • 1970-01-01
          • 1970-01-01
          • 2016-05-19
          • 1970-01-01
          相关资源
          最近更新 更多