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

lodash: aggregating and reducing array of objects based on date

本文关键字:对象 数组 日期 lodash      更新时间:2024-02-09

我是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
    }
]

目前,我已经写了一个非常不可读和复杂的代码,充满了if和fors,这是有效的。然而,我想使用lodash重构它。使用lodash可能吗?我环顾四周,找到了可能可以使用的_.reduce_.groupBy,但我现在很困惑,无法找到一个好的干净实现。

我们可以使用_.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;
},{}));

您不需要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此处