首页 > 解决方案 > create an array of objects grouped by date with count properties

问题描述

So I have an array of objects that have the following schema:

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

I need to convert them into an array of objects like so:

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

The way this is derived is by first grouping all objects together by date (updatedAt property). Then I would iterate over it to see which objects have a property isOpen set to true which means that they were added that day, or if its false they were removed on that day.

Kind of like this:

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

I hate to iterate over the arrays so many times. Is there a way to make this more efficient? Perhaps I can do the iterations in one loop somehow.

Thanks!

标签: javascriptarrays

解决方案


您可以像这样计算循环中的项目。您查找的对象将具有键(日期前缀)和计数,因此您不必再次映射。

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

推荐阅读