Reputation: 2896
I have an array of objects like this:
[{"ts":"Thu, 20 Aug 2015 18:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 17:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 16:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 15:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 16:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 15:00:00 GMT"}]
I am using something like this to traverse through each time:
_.each(times,function(t){
console.log(t.ts);
}, this);
I am using moment
to make sure that the dates all have the same end of day time, so as to ignore this variable. I would like to create a new object with a count of like times, e.g.
uniqueTimes =
{
{"Thu, 20 Aug 2015": 4},
{"Wed, 19 Aug 2015": 2}
}
Any suggestions on how to do this? I was thinking of traversing the uniqueTimes
object within the _.each
function, but I have hundreds of times, so on each iteration uniqueTimes
will be larger and larger. This doesn't seem efficient.
Upvotes: 3
Views: 101
Reputation: 96557
Based on your usage of _.each
it seems that you're using either LoDash or Underscore. In that case, both libraries have a handy _.countBy
method (LoDash docs, Underscore docs) that would allow you to get your desired results as shown below.
Instead of the whole split/join approach I'm using, you could also use the regex approach that adeneo shared.
var times = [{"ts":"Thu, 20 Aug 2015 18:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 17:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 16:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 15:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 16:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 15:00:00 GMT"}];
var groupedCounts = _.countBy(times, function(item) {
var split = item.ts.split(' ');
var value = split.slice(0, split.length - 2).join(' ');
return value;
});
document.body.innerHTML = '<pre>' + JSON.stringify(groupedCounts, null, 2) + '</pre>';
<script src="https://cdn.rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
Upvotes: 2
Reputation: 51931
With ES6 you can use Map() data structure for your task:
const result = data.reduce((m, i) => {
const key = i.ts; // or format your date with moment
return m.set(key, m.has(key) ? m.get(key) + 1 : 1);
}, new Map());
console.log(result);
Notice: check for Map compability in your environment.
Upvotes: 1
Reputation: 318372
You can just iterate and add to the unique times as you go
var times = [
{"ts":"Thu, 20 Aug 2015 18:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 17:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 16:00:00 GMT"},
{"ts":"Thu, 20 Aug 2015 15:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 16:00:00 GMT"},
{"ts":"Wed, 19 Aug 2015 15:00:00 GMT"}
];
var uniqueTimes = {};
times.forEach(function(time) {
var t = (time.ts.match(/^(.*?)\s\d+\:/) || [])[1];
t in uniqueTimes ? uniqueTimes[t]++ : uniqueTimes[t] = 1;
});
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueTimes, null, 4) + '</pre>';
Upvotes: 1