'Calculating Time Difference with Array.reduce
The following code uses array.reduce to return the time differences between start and stop as it iterates through the array.
As you can see, it's pretty basic and doesn't take into account events and task for example.
let data = [
{
action: "start",
time: 100
},
{
action: "stop",
time: 150
},
{
action: "start",
time: 250
},
{
action: "stop",
time: 350
},
{
action: "start",
time: 400
}
];
let end = 450; // should be Date.now(),
let sum = data.reduce(function (r, a) {
return r + (a.action === 'start' ? -a.time : a.time);
}, data[data.length - 1].action === 'start' ? end : 0);
console.log(sum);
I imagined the scalable version of this data array to be like this:
let data = [
{
activity: "JOB",
event: "CLOCK IN",
task: "TRAVEL",
desc: "Job #12345",
time: 100
},
{
activity: "JOB",
event: "CLOCK IN",
task: "ON SITE",
desc: "Job #12345",
time: 150
},
{
activity: "JOB",
event: "CLOCK IN",
task: "BREAK",
desc: "Job #12345",
time: 250
},
{
activity: "JOB",
event: "CLOCK IN",
task: "ON SITE",
desc: "Job #12345",
time: 350
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "HOME",
desc: "Job #12345",
time: 450
}
];
Array.reduce has been bit a challenge to learn so far. Any help would be appreciated.
How can I modify this code to iterate through scalable array?
Solution 1:[1]
If your data will eventually contain a stream of CLOCK IN and CLOCK OUT events for multiple jobs, a better example might be as follows:
const data = [
{
activity: "JOB",
event: "CLOCK IN",
task: "TRAVEL",
desc: "Job #1",
time: 100
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "ON SITE",
desc: "Job #1",
time: 150
},
{
activity: "JOB",
event: "CLOCK IN",
task: "BREAK",
desc: "Job #2",
time: 250
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "ON SITE",
desc: "Job #2",
time: 350
},
{
activity: "JOB",
event: "CLOCK IN",
task: "HOME",
desc: "Job #3",
time: 450
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "HOME",
desc: "Job #3",
time: 500
}
];
That shows CLOCK IN and CLOCK OUT events for three discrete jobs: Job #1, Job #2 and Job #3.
If I've got that right then the following code should give you what you need:
const jobs = data.reduce((prev,event)=>({
...prev,
[event.desc]:{
...prev[event.desc],
[event.event]:event.time
}
}),{})
That converts the data into an object that looks like this:
{
'Job #1': { 'CLOCK IN': 100, 'CLOCK OUT': 150 },
'Job #2': { 'CLOCK IN': 250, 'CLOCK OUT': 350 },
'Job #3': { 'CLOCK IN': 450, 'CLOCK OUT': 500 }
}
We can then enrich each of the job items in that object with the duration with this:
const result = Object.entries(jobs).reduce((prev,entry)=>{
const [key,value] = entry
return ({
...prev,
[key]:{
...value,
DURATION: value['CLOCK OUT'] - value['CLOCK IN']
}
})
}
,{})
The result is:
{
'Job #1': {
'CLOCK IN': 100,
'CLOCK OUT': 150,
DURATION: 50
},
'Job #2': {
'CLOCK IN': 250,
'CLOCK OUT': 350,
DURATION: 100
},
'Job #3': {
'CLOCK IN': 450,
'CLOCK OUT': 500,
DURATION: 50
}
}
How's that?
Working example below:
const data = [
{
activity: "JOB",
event: "CLOCK IN",
task: "TRAVEL",
desc: "Job #1",
time: 100
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "ON SITE",
desc: "Job #1",
time: 150
},
{
activity: "JOB",
event: "CLOCK IN",
task: "BREAK",
desc: "Job #2",
time: 250
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "ON SITE",
desc: "Job #2",
time: 350
},
{
activity: "JOB",
event: "CLOCK IN",
task: "HOME",
desc: "Job #3",
time: 450
},
{
activity: "JOB",
event: "CLOCK OUT",
task: "HOME",
desc: "Job #3",
time: 500
}
];
const jobs = data.reduce((prev,event)=>({
...prev,
[event.desc]:{
...prev[event.desc],
[event.event]:event.time
}
}),{});
const result = Object.entries(jobs).reduce((prev,entry)=>{
const [key,value] = entry
return ({
...prev,
[key]:{
...value,
DURATION: value['CLOCK OUT'] - value['CLOCK IN']
}
})
}
,{});
console.log(result);
Solution 2:[2]
If I understand you need 2 functions isStartType() and isStopType(). Both of them just a switch case return value. Or you just need 1 function isStartType() if you sure that you will not get an unexpected type. And after this just modify this a.action === 'start' to isStartType(a['propertyName'])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | suchislife |
| Solution 2 | EzioMercer |
