|
2 | 2 | Nitish Dayal, Software & Applications Developer - [Contact](http://nitishdayal.me) |
3 | 3 | Last Commit Date: Dec 24, 2016 |
4 | 4 |
|
| 5 | +The HTML document contains an _unordered list_ with multiple _list items_, each |
| 6 | + with a `data-time` which reflect a time in minutes and seconds. Our goal is to |
| 7 | + take all of these times and calculate the total in hours, minutes, and seconds. |
| 8 | + |
| 9 | +## Guide |
| 10 | + |
| 11 | +Alright friends, this one is fun. We do a lot of stuff with built-in array methods |
| 12 | + that help us handle the heavy lifting of this task. All we're responsible for is |
| 13 | + some light math, and even then we'll have some help from JavaScript operators. |
| 14 | + If you're not comfortable with `Array.prototype.map()`, `Array.prototype.reduce()`, |
| 15 | + or the `remainder (%) operator`, take a minute to look at the Mozilla documentation: |
| 16 | + |
| 17 | + - [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Map) |
| 18 | + - [Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) |
| 19 | + - [Remainder operator (%)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder_%28%29) _Take note of the difference between this and the `modulo` |
| 20 | + operator!_ |
| 21 | + |
| 22 | +To tackle this challenge, we'll begin by declaring a `constant` and defining it |
| 23 | + as an _array of HTML Node elements_ with a `data-time` property. Declare another |
| 24 | + `constant` that will be defined as the result of **mapping** over the array |
| 25 | + of node elements twice (the first map will return the _value_ of the `data-time` |
| 26 | + property, and the second will return the `data-time` property after converting it |
| 27 | + to an integer reflecting the time in seconds), and then **reducing** the array |
| 28 | + of integers down to a single integer value reflecting the _total of all times |
| 29 | + in seconds_. Now that we have the total in seconds, we need to declare a `constant` |
| 30 | + that will be defined as the time in **hours**, and another `constant` defined as |
| 31 | + the **remainder** of the seconds in minutes. To get the seconds remaining after |
| 32 | + calculating the hours, we can set a `let` variable as the **remainder** of the |
| 33 | + total seconds divided by the amount of seconds in an hour (3600). We can use this |
| 34 | + remainder to calculate the minutes. Finally, update the value of the `let` variable |
| 35 | + to reflect the seconds remaining after we've calculated the minutes. |
| 36 | + |
| 37 | +WOO! Now that you've got an idea of how we're going to approach this challenge, let's |
| 38 | + get to steppin'! |
| 39 | + |
| 40 | +**Steps:** |
| 41 | + |
| 42 | + 1. Declare a `const` and define as an _array of HTML Node elements_ with a `data-time` property. |
| 43 | + |
| 44 | + ```JavaScript |
| 45 | + // Option 1. Using the spread operator to convert the NodeList into an array |
| 46 | + const allTimes = [...document.querySelectorAll('[data-time]')] |
| 47 | + |
| 48 | + // Option 2. Converting the NodeList into an array using the `Array.from()` methods |
| 49 | + const allTimes = Array.from(document.querySelectorAll('[data-time]')) |
| 50 | + ``` |
| 51 | + |
| 52 | +2. Declare a `const` and define it as the _return value_ of **mapping** over each item |
| 53 | + in the array TWICE, and **reducing** the result of those maps to a single integer value. |
| 54 | + |
| 55 | + ```JavaScript |
| 56 | + const seconds = allTimes |
| 57 | + .map(listItem => listItem.dataset.time) // Get the 'data-time' property |
| 58 | + .map(timeValue => { |
| 59 | + /** Declare constants minutes & seconds using array destructuring |
| 60 | + * and define as the result of splitting the 'data-time' property |
| 61 | + * a list item at ':' and parsing the returned two strings |
| 62 | + * as float numbers |
| 63 | + */ |
| 64 | + const [minutes, seconds] = timeValue.split(':').map(parseFloat) |
| 65 | + return minutes * 60 + seconds // Return the total seconds |
| 66 | + }) |
| 67 | + // Add up all the seconds |
| 68 | + .reduce((runningTotal, seconds) => runningTotal + seconds) |
| 69 | + ``` |
| 70 | +3. Declare a `const` and define it as the seconds converted to hours. |
| 71 | + |
| 72 | + ```JavaScript |
| 73 | + const hours = Math.floor(seconds / 3600) |
| 74 | + ``` |
| 75 | + |
| 76 | +4. Declare a `let` variable and define it as the remaining seconds after |
| 77 | + calculating hours. |
| 78 | + |
| 79 | + ```JavaScript |
| 80 | + let secondsLeft = seconds % 3600 |
| 81 | + ``` |
| 82 | + |
| 83 | +5. Declare a `const` and define it as the remaining seconds converted to minutes. |
| 84 | + |
| 85 | + ```JavaScript |
| 86 | + const minutes = Math.floor(secondsLeft / 60) |
| 87 | + ``` |
| 88 | + |
| 89 | +6. Update the value of the `let` variable to reflect the remaining seconds after |
| 90 | + calculating the minutes. |
| 91 | + |
| 92 | + ```JavaScript |
| 93 | + secondsLeft %= 60 |
| 94 | + ``` |
| 95 | + |
| 96 | +7. Log out the values. |
| 97 | + |
| 98 | + ```JavaScript |
| 99 | + console.log(`Total video time: ${hours} hours, ${minutes} minutes, and ${secondsLeft} seconds`) |
| 100 | + ``` |
| 101 | +If your result is 4 hours, 58 minutes, and 58 seconds, you did it! WOOOOOO! Learning |
| 102 | + how to effectively use these array methods can greatly increase the clarity of your code |
| 103 | + and simplify your workflow. Learn them well! |
0 commit comments