JavaScript30 - Day 18 (Tally String Times)

This is day 18 in my #javascript30 journey. This is the free course from Wes Bos that lets you brush up on your JavaScript skills via 30 projects.

Yesterday we worked on a Sorting Band Names. You can keep track of all the projects we're building here.

Today we're learning how to tally string times with reduce.


Day 18 - Tally String Times with Reduce

We will be using the reduce() method to tally an array of string times. Before starting the lesson I spent some time reading the MDN docs (link above) about this method. It is important to go to understand the array methods that are available to us.

Our task today is to iterate over a list of videos and sum all of the time stamps that are found.

Each of our videos has a data-time attribute that contains a string value of their mm:ss time. So first up, we need to select all of the videos and collect up their associated data-time attribute value. We also need to spread this into an Array (instead of a nodeList):

const timeNodes = [...document.querySelectorAll('[data-time]')]  

Next up, we need to take the resulting array of strings and calculate the total number of seconds.

To do this we need to split the strings up into minutes & seconds. Then we need to convert these to numbers (multiplying the minutes by 60 as we go). Then we need to sum all of the resulting numbers:

const seconds = timeNodes  
  .map(node => node.dataset.time)
  .map(timeCode => {
    const [mins, secs] = timeCode.split(':').map(parseFloat)
    return (mins * 60) + secs
  })
  .reduce((total, vidSeconds) => total +  vidSeconds)

Now we need to convert this single number of seconds into a human readable HH:MM:SS format. We will use the Remainder (%) arithmic operator heavily in these calculations.

let secondsLeft = seconds  
const hours = Math.floor(secondsLeft / 3600)  
secondsLeft = secondsLeft % 3600  
const minutes = Math.floor(secondsLeft / 60)  
secondsLeft = secondsLeft % 60

console.log('Total Video Time: ' + hours + ':' + minutes + ':' + secondsLeft)  

As there is no interactivity available in today's project I have opted not to publish it.

You can keep track of all the projects in this JavaScript30 challenge here.