AldoTheApache - 8 months ago 34

Javascript Question

I'm playing with a data set that counts the number of commits a person makes at a certain hour. I can create an array objects for the hour a person made a commit and how many times they committed:

`[ { 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 } ]

Where I'm stuck is trying to fill in the missing hours. So in the example above, I would need to include the hours where no commits were made. I'm using a 0-24 range for an entire day. This is what I'm hoping to get as a result:

`[`

{ 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 }

]

Here is the function I'm using to create these objects:

`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;

};

How can I add the missing times? I was thinking of creating a list (0-24) and then seeing if an hour is not in the list to add it with a value of zero to the object. Not sure how that can be accomplished.

Answer

How about just initializing `commitHourList`

such that it contains all hours with `0`

commits and then fill it up with actual data:

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

This way, whatever hour you don't add will automatically have `0`

commits.

**Note**: using `range`

then `map`

to initialize the array is less code but does iterate the array twice each time. A more performant way would be to create this array once in some utility and then copy it each time you need a new one.

For example:

```
// 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();
}
})();
```

And then use it like:

```
var commitHourList = getHoursArray();
```

Using `slice`

is usually the most performant way of copying an array but here are other possibilities

Source (Stackoverflow)