使用下划线填充数组中缺少的对象

Filling in missing objects in an array using Underscore

本文关键字:对象 数组 下划线 填充      更新时间:2023-09-26

我正在使用一个数据集,该数据集计算一个人在特定时间内提交的数量。我可以创建一个数组对象,记录一个人提交的时间和提交的次数:

[ { hour: '6', commits: 2 },
  { hour: '7', commits: 6 },
  { hour: '8', commits: 6 },
  { hour: '9', commits: 4 },
  { hour: '10', commits: 4 },
  { hour: '11', commits: 6 },
  { hour: '12', commits: 18 },
  { hour: '13', commits: 18 },
  { hour: '14', commits: 14 },
  { hour: '15', commits: 30 },
  { hour: '16', commits: 24 },
  { hour: '17', commits: 18 },
  { hour: '18', commits: 24 },
  { hour: '19', commits: 22 },
  { hour: '20', commits: 6 },
  { hour: '21', commits: 16 },
  { hour: '22', commits: 8 } ]

我被困的地方是试图填补缺失的时间。所以在上面的例子中,我需要包括没有提交的时间。我一整天都在用0-24的范围。这是我希望得到的结果:

[
  { hour: '0', commits: 0 }, 
  { hour: '1', commits: 0 },
  { hour: '2', commits: 0 },
  { hour: '3', commits: 0 },
  { hour: '4', commits: 0 },
  { hour: '5', commits: 0 },
  { hour: '6', commits: 2 },
  { hour: '7', commits: 6 },
  { hour: '8', commits: 6 },
  { hour: '9', commits: 4 },
  { hour: '10', commits: 4 },
  { hour: '11', commits: 6 },
  { hour: '12', commits: 18 },
  { hour: '13', commits: 18 },
  { hour: '14', commits: 14 },
  { hour: '15', commits: 30 },
  { hour: '16', commits: 24 },
  { hour: '17', commits: 18 },
  { hour: '18', commits: 24 },
  { hour: '19', commits: 22 },
  { hour: '20', commits: 6 },
  { hour: '21', commits: 16 },
  { hour: '22', commits: 8 },
  { hour: '23', commits: 0 },
  { hour: '24', commits: 0 }
]
下面是我用来创建这些对象的函数:
var getAuthorAndHourCounts = (groupedByAuthor) => {
  var result = _.map(groupByAuthor, (value, key, list) => {
    var author = key;
    var hours = _.countBy(value, 'hour');
    var commitHourList = [];
    _.each(hours, (v,k) => {
      var obj = {};
      obj.hour = k;
      obj.commits = v;
      commitHourList.push(obj);
    });
    return {
      person: author,
      times: commitHourList
    };
  });
  return result;
};

如何添加缺失的次数?我正在考虑创建一个列表(0-24),然后看看一个小时是否不在列表中,以0的值将其添加到对象。我不知道怎么才能做到。

如何初始化commitHourList,使其包含0提交的所有小时数,然后用实际数据填充它:

// initialize commitHourList with 24 objects 
// one for each hour and each with 0 commits
var commitHourList = _.range(24).map((hour) => ({ hour, commits: 0 }));
// for every received hour, add proper commits
_.each(hours, (commits, hour) => {
  commitHourList[hour].commits = commits;
});

这样,无论你没有添加多少小时,都会自动有0提交。

注意:使用range然后map初始化数组的代码较少,但每次迭代数组两次。更高效的方法是在某个实用程序中创建此数组,然后在每次需要新数组时复制它。

例如:

// utility that creates the hours array when initialized
// and returns a function that will return a copy of the hours array on each call
var getHoursArray = (function() {
  var arr =  _.range(24).map((hour) => ({ hour, commits: 0 }));
  return function() {
    return arr.slice();
  }
})();

然后像这样使用:

var commitHourList = getHoursArray();

使用slice通常是最高效的复制数组的方式,但这里有其他的可能性