Reputation: 1517
I need to split an array of objects in a shape of
{
eventStart: 1575621000000,
data: 'Some data' // not relevant
}
by chunks of 2 hours span, starting with every hour on the hour (beginning of hour), like: 10.00 - 12.00, 12.00 - 14.00, etc
this is what I came up with but don't think it's anywhere near performant solution:
Please note the day
which is just a moment().startOf('day') const
data => data.reduce((acc, { eventStart, ...rest }) => {
if (moment(eventStart).isBetween(moment(day).add(8, 'hours'), moment(day).add(10, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '8-10': [...acc['8-10'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(10, 'hours'), moment(day).add(12, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '10-12': [...acc['10-12'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(12, 'hours'), moment(day).add(14, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '12-14': [...acc['12-14'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(14, 'hours'), moment(day).add(16, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '14-16': [...acc['14-16'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(16, 'hours'), moment(day).add(18, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '16-18': [...acc['16-18'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(18, 'hours'), moment(day).add(20, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '18-20': [...acc['18-20'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(20, 'hours'), moment(day).add(22, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '20-22': [...acc['20-22'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(22, 'hours'), moment(day).add(24, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '22-24': [...acc['22-24'], rest] }
)
}
return acc
}, {
'8-10': [],
'10-12': [],
'12-14': [],
'14-16': [],
'16-18': [],
'18-20': [],
'20-22': [],
'22-24': []
})
I am cool with Lodash approach if anyone comes up with one.
Example data:
[{"data":42986084,"eventStart":1575621000000},{"data":43729858,"eventStart":1575626400000},{"data":43738365,"eventStart":1575626400000},{"data":43738483,"eventStart":1575626400000},{"data":43688900,"eventStart":1575626400000},{"data":43701367,"eventStart":1575628200000},{"data":43701506,"eventStart":1575628200000},{"data":43675303,"eventStart":1575621000000},{"data":43690259,"eventStart":1575621000000},{"data":43695785,"eventStart":1575628200000},{"data":43695820,"eventStart":1575628200000},{"data":43695827,"eventStart":1575628200000},{"data":43699341,"eventStart":1575628200000},{"data":43699369,"eventStart":1575628200000},{"data":43699424,"eventStart":1575628200000},{"data":43699428,"eventStart":1575628200000},{"data":43700003,"eventStart":1575628200000},{"data":43701004,"eventStart":1575628200000},{"data":43698552,"eventStart":1575628200000},{"data":43741641,"eventStart":1575619200000},{"data":43741909,"eventStart":1575619200000},{"data":43739045,"eventStart":1575624600000},{"data":43742137,"eventStart":1575624600000},{"data":43742680,"eventStart":1575619200000},{"data":43744043,"eventStart":1575619200000},{"data":43784844,"eventStart":1575619200000},{"data":43785707,"eventStart":1575624600000},{"data":43764294,"eventStart":1575621900000},{"data":43787721,"eventStart":1575622800000},{"data":43787722,"eventStart":1575622800000},{"data":43787723,"eventStart":1575622800000},{"data":43787737,"eventStart":1575622800000},{"data":43767839,"eventStart":1575621600000},{"data":43726394,"eventStart":1575626400000},{"data":43810835,"eventStart":1575628200000},{"data":43725116,"eventStart":1575618600000},{"data":43793011,"eventStart":1575622800000},{"data":43793046,"eventStart":1575626400000},{"data":43793062,"eventStart":1575628200000},{"data":43737559,"eventStart":1575619200000},{"data":43737939,"eventStart":1575619200000},{"data":43737938,"eventStart":1575624600000},{"data":43792981,"eventStart":1575624600000},{"data":43735362,"eventStart":1575621600000},{"data":43784352,"eventStart":1575619200000},{"data":43784392,"eventStart":1575619200000},{"data":43731320,"eventStart":1575624600000},{"data":43732363,"eventStart":1575624600000},{"data":43785780,"eventStart":1575622800000},{"data":43785782,"eventStart":1575622800000},{"data":43785790,"eventStart":1575628200000},{"data":43785792,"eventStart":1575628200000},{"data":43780474,"eventStart":1575621000000},{"data":43780213,"eventStart":1575624000000},{"data":43811157,"eventStart":1575626400000},{"data":43811324,"eventStart":1575626400000},{"data":43811121,"eventStart":1575628200000},{"data":41965260,"eventStart":1575624600000},{"data":43793228,"eventStart":1575622800000},{"data":43735069,"eventStart":1575626400000},{"data":43550395,"eventStart":1575621000000},{"data":43550795,"eventStart":1575628200000},{"data":43674957,"eventStart":1575619200000},{"data":43675056,"eventStart":1575619500000},{"data":43699933,"eventStart":1575626400000},{"data":43700079,"eventStart":1575626400000},{"data":43735147,"eventStart":1575626400000},{"data":43735110,"eventStart":1575626400000},{"data":43732832,"eventStart":1575626400000},{"data":43732877,"eventStart":1575626400000},{"data":43733772,"eventStart":1575626400000},{"data":43761754,"eventStart":1575626400000},{"data":43694264,"eventStart":1575622800000},{"data":43748186,"eventStart":1575626400000},{"data":43720156,"eventStart":1575622800000},{"data":43720671,"eventStart":1575622800000},{"data":43589280,"eventStart":1575626400000},{"data":43593385,"eventStart":1575626400000},{"data":43757509,"eventStart":1575619200000},{"data":43757556,"eventStart":1575621000000},{"data":43535382,"eventStart":1575619200000},{"data":43371974,"eventStart":1575626400000},{"data":43752370,"eventStart":1575621000000},{"data":43752371,"eventStart":1575621000000},{"data":43784503,"eventStart":1575619080000},{"data":43784761,"eventStart":1575620400000},{"data":43784650,"eventStart":1575621720000},{"data":43784748,"eventStart":1575623040000},{"data":43784836,"eventStart":1575624360000},{"data":43785638,"eventStart":1575625680000},{"data":43727654,"eventStart":1575619800000},{"data":43727744,"eventStart":1575622200000},{"data":43727655,"eventStart":1575624600000},{"data":43727728,"eventStart":1575627000000}]
Expected output would be any iterable form really. An example might be the initialValue in reduce function:
{
'8-10': [], // nothing found for this criteria
'10-12': [
{
eventStart: 1575626400000,
data: 444
},
{
eventStart: 1575626400000,
data: 555
}
], // 2 objects fit the 10-12 range
'12-14': [], // nothing found for this criteria
'14-16': [], // nothing found for this criteria
'16-18': [], // nothing found for this criteria
'18-20': [], // nothing found for this criteria
'20-22': [], // nothing found for this criteria
'22-24': [] // nothing found for this criteria
}
Adding a code snippet for the question for others to run and work on
day = moment().startOf('day')
data = [{"data":42986084,"eventStart":1575621000000},{"data":43729858,"eventStart":1575626400000},{"data":43738365,"eventStart":1575626400000},{"data":43738483,"eventStart":1575626400000},{"data":43688900,"eventStart":1575626400000},{"data":43701367,"eventStart":1575628200000},{"data":43701506,"eventStart":1575628200000},{"data":43675303,"eventStart":1575621000000},{"data":43690259,"eventStart":1575621000000},{"data":43695785,"eventStart":1575628200000},{"data":43695820,"eventStart":1575628200000},{"data":43695827,"eventStart":1575628200000},{"data":43699341,"eventStart":1575628200000},{"data":43699369,"eventStart":1575628200000},{"data":43699424,"eventStart":1575628200000},{"data":43699428,"eventStart":1575628200000},{"data":43700003,"eventStart":1575628200000},{"data":43701004,"eventStart":1575628200000},{"data":43698552,"eventStart":1575628200000},{"data":43741641,"eventStart":1575619200000},{"data":43741909,"eventStart":1575619200000},{"data":43739045,"eventStart":1575624600000},{"data":43742137,"eventStart":1575624600000},{"data":43742680,"eventStart":1575619200000},{"data":43744043,"eventStart":1575619200000},{"data":43784844,"eventStart":1575619200000},{"data":43785707,"eventStart":1575624600000},{"data":43764294,"eventStart":1575621900000},{"data":43787721,"eventStart":1575622800000},{"data":43787722,"eventStart":1575622800000},{"data":43787723,"eventStart":1575622800000},{"data":43787737,"eventStart":1575622800000},{"data":43767839,"eventStart":1575621600000},{"data":43726394,"eventStart":1575626400000},{"data":43810835,"eventStart":1575628200000},{"data":43725116,"eventStart":1575618600000},{"data":43793011,"eventStart":1575622800000},{"data":43793046,"eventStart":1575626400000},{"data":43793062,"eventStart":1575628200000},{"data":43737559,"eventStart":1575619200000},{"data":43737939,"eventStart":1575619200000},{"data":43737938,"eventStart":1575624600000},{"data":43792981,"eventStart":1575624600000},{"data":43735362,"eventStart":1575621600000},{"data":43784352,"eventStart":1575619200000},{"data":43784392,"eventStart":1575619200000},{"data":43731320,"eventStart":1575624600000},{"data":43732363,"eventStart":1575624600000},{"data":43785780,"eventStart":1575622800000},{"data":43785782,"eventStart":1575622800000},{"data":43785790,"eventStart":1575628200000},{"data":43785792,"eventStart":1575628200000},{"data":43780474,"eventStart":1575621000000},{"data":43780213,"eventStart":1575624000000},{"data":43811157,"eventStart":1575626400000},{"data":43811324,"eventStart":1575626400000},{"data":43811121,"eventStart":1575628200000},{"data":41965260,"eventStart":1575624600000},{"data":43793228,"eventStart":1575622800000},{"data":43735069,"eventStart":1575626400000},{"data":43550395,"eventStart":1575621000000},{"data":43550795,"eventStart":1575628200000},{"data":43674957,"eventStart":1575619200000},{"data":43675056,"eventStart":1575619500000},{"data":43699933,"eventStart":1575626400000},{"data":43700079,"eventStart":1575626400000},{"data":43735147,"eventStart":1575626400000},{"data":43735110,"eventStart":1575626400000},{"data":43732832,"eventStart":1575626400000},{"data":43732877,"eventStart":1575626400000},{"data":43733772,"eventStart":1575626400000},{"data":43761754,"eventStart":1575626400000},{"data":43694264,"eventStart":1575622800000},{"data":43748186,"eventStart":1575626400000},{"data":43720156,"eventStart":1575622800000},{"data":43720671,"eventStart":1575622800000},{"data":43589280,"eventStart":1575626400000},{"data":43593385,"eventStart":1575626400000},{"data":43757509,"eventStart":1575619200000},{"data":43757556,"eventStart":1575621000000},{"data":43535382,"eventStart":1575619200000},{"data":43371974,"eventStart":1575626400000},{"data":43752370,"eventStart":1575621000000},{"data":43752371,"eventStart":1575621000000},{"data":43784503,"eventStart":1575619080000},{"data":43784761,"eventStart":1575620400000},{"data":43784650,"eventStart":1575621720000},{"data":43784748,"eventStart":1575623040000},{"data":43784836,"eventStart":1575624360000},{"data":43785638,"eventStart":1575625680000},{"data":43727654,"eventStart":1575619800000},{"data":43727744,"eventStart":1575622200000},{"data":43727655,"eventStart":1575624600000},{"data":43727728,"eventStart":1575627000000}]
res = data.reduce((acc, { eventStart, ...rest }) => {
if (moment(eventStart).isBetween(moment(day).add(8, 'hours'), moment(day).add(10, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '8-10': [...acc['8-10'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(10, 'hours'), moment(day).add(12, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '10-12': [...acc['10-12'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(12, 'hours'), moment(day).add(14, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '12-14': [...acc['12-14'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(14, 'hours'), moment(day).add(16, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '14-16': [...acc['14-16'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(16, 'hours'), moment(day).add(18, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '16-18': [...acc['16-18'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(18, 'hours'), moment(day).add(20, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '18-20': [...acc['18-20'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(20, 'hours'), moment(day).add(22, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '20-22': [...acc['20-22'], rest] }
)
}
if (moment(eventStart).isBetween(moment(day).add(22, 'hours'), moment(day).add(24, 'hours'))) {
acc = Object.assign(
{},
acc,
{ '22-24': [...acc['22-24'], rest] }
)
}
return acc
}, {
'8-10': [],
'10-12': [],
'12-14': [],
'14-16': [],
'16-18': [],
'18-20': [],
'20-22': [],
'22-24': []
})
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
Upvotes: 2
Views: 235
Reputation: 191976
You can use lodash's _.groupBy()
and generate the key by creating a date from eventStart
, rounding down to the closest even hour (start
), and returning a range of start - start + 2:
const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}];
const result = _.groupBy(data, o => {
const hour = new Date(o.eventStart).getHours(); // get the hour
const start = hour - hour % 2; // normalize to the closest even hour
return `${start}-${start + 2}`; // get the key
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
And the same idea using Array.reduce()
:
const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}];
const createRangeKey = eventStart => {
const hour = new Date(eventStart).getHours(); // get the hour
const start = hour - hour % 2; // normalize to the closest even hour
return `${start}-${start + 2}`; // get the key
};
const result = data.reduce((r, o) => {
const key = createRangeKey(o.eventStart); // get the key
if(!r[key]) r[key] = []; // init if not existing on the object
r[key].push(o); // add the object to the key
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you need to filter out hours that are not in the 8-24 range, you can check if the start
is less than 8. In this example {"data":"ignore","eventStart": 1575669600000}
would be ignored.
const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}, {"data":"ignore","eventStart": 1575669600000}];
const result = data.reduce((r, o) => {
const hour = new Date(o.eventStart).getHours(); // get the hour
const start = hour - hour % 2; // normalize to the closest even hour
if(start < 8) return r;
const key = `${start}-${start + 2}`; // get the key
if(!r[key]) r[key] = []; // init if not existing on the object
r[key].push(o); // add the object to the key
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3