lodash:根据日期聚合和减少对象数组

lodash: aggregating and reducing array of objects based on date

我是 Lodash 和函数式编程概念的新手。所以,我有一组对象,这些对象的日期是这样的:

[
    {
         "date": '1-Jan-2015',
         "count": 4 
    },
    {
         "date": '4-Jan-2015',
         "count": 3 
    },
    {
         "date": '1-Feb-2015',
         "count": 4 
    },
    {
         "date": '18-Feb-2015',
         "count": 10 
    }
]

我想以这样一种方式减少和聚合它,即我得到一个对象数组,其中每个对象都有月度数据而不是像这样的按天计算的数据:

[
    {
        "date": 'Jan, 2015',
        "count": 7 // aggregating the count of January
    },
    {
        "date": 'Feb, 2015',
        "count": 14 //aggregating the count of February
    }
]

目前,我编写了一段非常难读且令人费解的代码,其中充满了 ifs 和 fors,但它有效。但是,我想使用 lodash 重构它。可以使用 lodash 吗?我环顾四周,发现 _.reduce_.groupBy 我可能会用到它们,但我现在很困惑,想不出一个好的干净的实现。

你不需要 lodash 来实现你想要的,你可以使用普通的旧 Javascript:

var array = [{
  "date": '1-Jan-2015',
  "count": 4
}, {
  "date": '4-Jan-2015',
  "count": 3
}, {
  "date": '1-Feb-2015',
  "count": 4
}, {
  "date": '18-Feb-2015',
  "count": 10
}]

var result = array.reduce(function(ar, item) {
  var index = item.date.split('-').slice(1,3).join(', ') //getting date Month-Year
  _item = ar.filter(function(a) { 
    return a.date === index
  })[0] // getting item if already present in array

  // getting index of _item if _item is already present in ar
  indexOf = ar.indexOf(_item) 

  if(indexOf > -1)
    // we sum the count of existing _item
    ar[indexOf] = {date: index, count: count: _item.count + item.count } 
  else
    // item is not yet in the array, we push a new _item
    ar.push({date: index, count: item.count}) 

  return ar; // return the array as required by reduce
}, []) // initialize the reduce method with an empty array

console.log(result) // your array with aggregated dates

为了好玩,lodash 版本:

_.values(array.reduce(function(obj, item) {
  var index = item.date.split('-').slice(1, 3).join(', ')
  obj[index] = {date: index, count: (obj[index] && obj[index].count || 0) + item.count}
  return obj
}, {}))

jsfiddle here

我们可以使用 _.reduce & _.values

var arr = [
    {
         "date": '1-Jan-2015',
         "count": 4 
    },
    {
         "date": '4-Jan-2015',
         "count": 3 
    },
    {
         "date": '1-Feb-2015',
         "count": 4 
    },
    {
         "date": '18-Feb-2015',
         "count": 10 
    }
]

_.values(_.reduce(arr,function(result,obj){
  var name = obj.date.split('-');
  name = name[1]+', '+name[2];  
  result[name] = {
    date:name,
    count:obj.count + (result[name]?result[name].count:0)
  };
  return result;
},{}));