Reputation: 525
I have an array like this,
[
{id: 1, name: "sleep", endTime: 1600261550535, startTime: 1600261541729}, // 9 sec
{id: 2, name: "sleep", endTime: 1600261527833, startTime: 1600261522709}, // 5 sec
{id: 3, name: "sleep", endTime: 1600261496881, startTime: 1600261437616}, // 59 sec
{id: 4, name: "awake", endTime: 1600261427129, startTime: 1600261413596}, // 14 sec
{id: 5, name: "awake", endTime: 1600261403114, startTime: 1600261347569}, // 56 sec
{id: 6, name: "awake", endTime: 1600261337893, startTime: 1600261206497}, // 2 min 11 sec
]
I need to work out the the total time(duration) when all of the object with the same name
are added together. The time format should be in hr, min, sec.
Obviously it's easy to get the duration of one of them at a time but I cant think a way to add up duration of together.
Help is much appreciated. Thanks. Feel free to use moment or lodash
Output should be
total duration sleep : 1 min 13 secs
total duration awake : 3 min 21 secs
Edit: Thank you all so much for your response, You guys are what makes the community better.
Upvotes: 0
Views: 116
Reputation: 21
This was a fun code challenge. I hope it helps you get to your final goal.
const getSleepAndDuration = (array) => {
const finalTimesInSeconds = array.reduce(
(accum, current) => {
const start = moment(current.startTime);
const end = moment(current.endTime);
const diffInSeconds = end.diff(start, "seconds");
accum[current.name] += diffInSeconds;
return accum;
},
{
sleep: 0,
awake: 0,
}
);
const { sleep, awake } = finalTimesInSeconds;
const sleepText = getDurationText(sleep);
const awakeText = getDurationText(awake);
console.log(`total duration sleep: ${sleepText}`);
console.log(`total duration awake: ${awakeText}`);
};
const getDurationText = (duration) => {
const days = Math.floor(duration / 86400);
const hours = Math.floor((duration - days * 86400) / 3600);
const minutes = Math.floor((duration - days * 86400 - hours * 3600) / 60);
const seconds = Math.floor(
duration - days * 86400 - hours * 3600 - minutes * 60
);
let time = "";
if (days) {
time += `${days} ${days === 1 ? "day" : "days"}`;
}
if (hours) {
time += ` ${hours} ${hours === 1 ? "hour" : "hours"}`;
}
if (minutes) {
time += ` ${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
}
if (seconds) {
time += ` ${seconds} ${seconds === 1 ? "second" : "seconds"}`;
}
return time;
};
Upvotes: 1
Reputation: 50759
You can accumulate the object based on the name
into a Map
using reduce. Once you have performed the accumulation/summation you can use Array.from on your Map with a mapping function to convert the values of your map into the desired format you're after. You can then forEach/loop over the entries of the map and print out the keys/values:
const arr = [ {id: 1, name: "sleep", endTime: 1600261550535, startTime: 1600261541729}, {id: 2, name: "sleep", endTime: 1600261527833, startTime: 1600261522709}, {id: 3, name: "sleep", endTime: 1600261496881, startTime: 1600261437616}, {id: 4, name: "awake", endTime: 1600261427129, startTime: 1600261413596}, {id: 5, name: "awake", endTime: 1600261403114, startTime: 1600261347569}, {id: 6, name: "awake", endTime: 1600261337893, startTime: 1600261206497}];
const ppTime = s => {
const hours = Math.floor(s / 3600);
const min = Math.floor(s / 60) % 60
const secs = s % 60;
return [[hours, 'hours'], [min, 'min'], [secs, 'secs']].filter(([f]) => f).map(arr => arr.join(' ')).join(' ');
}
const res = Array.from(arr.reduce((m, {name, endTime, startTime}) => {
return m.set(name, (m.get(name) || 0) + (endTime - startTime));
}, new Map), ([k, v]) => [k, ppTime(Math.round(v/1000))]);
res.forEach(([name, time]) => {
console.log(`total duration ${name} : ${time}`);
});
Upvotes: 1
Reputation: 1216
try this:
var timeStamps = [
{id: 1, name: "sleep", endTime: 1600261550535, startTime: 1600261541729}, // 9 sec
{id: 2, name: "sleep", endTime: 1600261527833, startTime: 1600261522709}, // 5 sec
{id: 3, name: "sleep", endTime: 1600261496881, startTime: 1600261437616}, // 59 sec
{id: 4, name: "awake", endTime: 1600261427129, startTime: 1600261413596}, // 14 sec
{id: 5, name: "awake", endTime: 1600261403114, startTime: 1600261347569}, // 56 sec
{id: 6, name: "awake", endTime: 1600261337893, startTime: 1600261206497}, // 2 min 11 sec
];
var sleep = 0;
var awake = 0;
timeStamps.forEach((element) => {
if(element.name == "sleep") {
sleep = sleep + element.endTime-element.startTime;}
if(element.name == "awake") {
awake = awake + element.endTime-element.startTime;}});
var date = new Date(sleep);
var date1 = new Date(awake);
var sleepMinutes = date.getMinutes();
var sleepSeconds = date.getSeconds();
var awakeMinutes = date1.getMinutes();
var awakeSeconds = date1.getSeconds();
console.log("total amount of sleep: %s min %s sec",sleepMinutes, sleepSeconds);
console.log("total amount of awake: %s min %s sec",awakeMinutes, awakeSeconds);
Upvotes: 1
Reputation: 12939
This is working for me:
let res = [
{id: 1, name: "sleep", endTime: 1600261550535, startTime: 1600261541729}, // 9 sec
{id: 2, name: "sleep", endTime: 1600261527833, startTime: 1600261522709}, // 5 sec
{id: 3, name: "sleep", endTime: 1600261496881, startTime: 1600261437616}, // 59 sec
{id: 4, name: "awake", endTime: 1600261427129, startTime: 1600261413596}, // 14 sec
{id: 5, name: "awake", endTime: 1600261403114, startTime: 1600261347569}, // 56 sec
{id: 6, name: "awake", endTime: 1600261337893, startTime: 1600261206497}, // 2 min 11 sec
];
// accumulate the differences in milliseconds
res = res.reduce((a, e) => {
a[e.name] = (a[e.name] || 0) + Math.abs(e.endTime - e.startTime);
return a;
}, {})
// print the output extracting minutes and seconds
Object.entries(res).map(([k, v]) => {
let minutes = Math.floor(v / 60000);
let seconds = Math.floor((v - minutes * 60000) / 1000)
console.log(`${k} : ${minutes} minutes and ${seconds}`)
})
Upvotes: 1
Reputation: 187
let sleepResult = 0;
let awakeResult = 0;
array.forEach(item => {
const diff = item.endTime - item.startTime
if (item.name === 'sleep')
sleepResult += diff
if (item.name === 'awake')
awakeResult += diff
})
console.log(`total duration sleep : ${sleepResult}`)
console.log(`total duration awake : ${awakeResult}`)
This will allow you to achieve what you asked.
Assuming you will format final log as
1 min 13 secs
Since sleepResult
and awakeResult
are timestamps
Upvotes: 1