今天的實作算是練習之前Array的函式,map()和reduce()。這個練習是假設我們在youtube有一堆影片列表,後面顯示每部影片的時間長度,那我們要怎麼把這些時間加總起來。
實作範例
將NodeList轉成Array:前面課程也有提過,document.querySelectorAll()所取得的列表是NodeList不是Array,因此要先轉成Array才能用Array的函式。而轉換的方法如下:
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
map()與reduce():這也是之前課程提到過的Array兩個重要的方法,那我們直接看這次練習怎麼用的
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);
Array的函式都是將每個成員都跑過一遍,所以第一個map()是將每個element的data-time屬性值取出來變成一個Array。由於前一個map()取出來的值是"min:sec"這種格式,所以第二個map()是先將字串split分割成min跟sec,再將min*60,與sec相加。這邊要注意,因為split完仍是字串,所以要再用一個map()將min和sec做parseFloat(),轉成數字才能相加。
而reduce()部分的兩個參數,一個是每次迴圈跑完的結果,一個是Array的成員。所以reduce((total, vidSeconds) => total + vidSeconds)
就是把每個秒數累加,最後變成一個值。
將加總的秒轉成hr:min:sec:將總秒數除以3600即為hr,而餘數再除以60,即為min,最後的餘數就是秒
let secondsLeft = seconds;
const hours = Math.floor(secondsLeft / 3600);
secondsLeft = secondsLeft % 3600;
const mins = Math.floor(secondsLeft / 60);
secondsLeft = secondsLeft % 60;
console.log(hours, mins, secondsLeft);