创建一个按日期分组并具有count属性的对象数组

时间:2018-08-23 20:49:00

标签: javascript arrays

所以我有一个具有以下架构的对象数组:

{
    "isOpen" : false, 
    "updatedAt" : "2018-08-23T14:44:31.651+0000"
}

我需要将它们转换为对象数组,如下所示:

{
    date: "2018-08-23",
    added: 1,
    removed: 2
}

此方法的派生方法是先按日期将所有对象分组在一起(updatedAt属性)。然后,我将对其进行迭代,以查看哪些对象的属性isOpen设置为true,这意味着它们是在当天添加的,或者如果对象是false,则是在当天删除的。

这类的:

var data = {};
dataArray.forEach(function (item) {
    var key = item.updatedAt.split('T')[0];
    if(data.hasOwnProperty(key)){
        if(item.isOpen) data[key].added = data[key].added + 1;
        else data[key].removed = data[key].removed + 1;
    } else {
        if(item.isOpen) data[key] = {added: 1, removed: 0};
        else data[key] = {added: 0, removed: 1};
    }
});
var final = Object.keys(data).map(function (key) {
    return {
        date: key,
        added: data[key].added,
        removed: data[key].removed
    };
});

我讨厌遍历数组很多次。有没有办法使它更有效?也许我可以以某种方式在一个循环中进行迭代。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以像这样在循环中计数您的物品。您要查找的对象将具有键(日期前缀)并进行计数,因此您无需再次映射。

var ret = {}
dataArray.forEach(function(item) {
  var date = item.updatedAt.split('T')[0];
  let counts = ret[date]
  if (!counts) {
    counts = {
      date,
      added: 0,
      removed: 0
    }
    ret[date] = counts
  }

  if (item.isOpen) counts.added++
    else counts.removed++;
})

var output = ret.values

答案 1 :(得分:1)

这似乎很好地使用了reduce,它将减少代码的使用量。然后,只需在创建哈希图时添加日期即可。如果这样做,最终数组将在Object.values()的结果中等待:

let dataArray = [{"isOpen" : false, "updatedAt" : "2018-08-23T14:44:31.651+0000"},{"isOpen" : true, "updatedAt" : "2018-08-23T14:44:31.651+0000"},{"isOpen" : true, "updatedAt" : "2018-08-23T14:44:31.651+0000"},{"isOpen" : false, "updatedAt" : "2018-07-23T14:44:31.651+0000"},{"isOpen" : false, "updatedAt" : "2018-07-23T14:44:31.651+0000"},{"isOpen" : true, "updatedAt" : "2018-07-23T14:44:31.651+0000"},{"isOpen" : true, "updatedAt" : "2018-08-23T14:44:31.651+0000"}]

let data = dataArray.reduce((data, item) => {
    let key = item.updatedAt.split('T')[0];
    let current = (data[key] || (data[key] = {date: key, added: 0, removed: 0}))
    current[item.isOpen ? 'added' : 'removed']  += 1
    return data
}, {});

console.log(Object.values(data))

答案 2 :(得分:0)

您可以使用软件包jinqJS。

有一个 groupby 子句可能有用

https://jinqjs.readme.io/docs/groupby