First define a couple of utility functions:
// utility functions
// displays time inside each li
function addSpanToHTML(el) {
const span = document.createElement('span');
span.innerHTML = `<span class="video-time">${el.dataset.time}</span>`;
el.appendChild(span);
return el;
}
// logs whatever is passed to it
// and can be inserted into map()
// because it returns the passed data
function logIt(el) {
console.log(el);
return el;
}
// converts seconds (int) to time (string)
function convertSecondsToTime(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600);
let secondsRemaining = totalSeconds % (hours*3600);
const mins = Math.floor(secondsRemaining / 60);
const seconds = secondsRemaining % (mins*60);
return `${hours}:${mins}:${seconds}`;
}
This first attempt is really verbose, but it is super readable, and makes heavy use of composition.
const videoElems = [...document.querySelectorAll('[data-time]')];
function extractTimeString(el) {
return el.dataset.time;
}
function splitTimeString(timeString) {
return timeString.split(':');
}
function calcTimeInSeconds(timeArray) {
const [mins, seconds] = timeArray;
return parseFloat(mins) * 60 + parseFloat(seconds);
}
function calcTotalSeconds(total, curr) {
return total += curr;
}
logIt(
convertSecondsToTime(
logIt(videoElems
.map(addSpanToHTML)
.map(extractTimeString)
.map(splitTimeString)
.map(calcTimeInSeconds)
.reduce(calcTotalSeconds, 0)
) // 17938
)
); // 4:58:58
This next attempt focuses on brevity, and uses the same utility functions.
const videoElems2 = [...document.querySelectorAll('[data-time]')];
const totalTimeinSeconds = videoElems2.reduce( (total, curr) => {
const [mins, seconds] = curr.dataset.time.split(':');
total += parseFloat(mins) * 60 + parseFloat(seconds);
return total;
}, 0);
logIt(
convertSecondsToTime(
logIt(totalTimeinSeconds) // 17938
)
); // 4:58:58