[JavaScript 30]Day18-Tally String Times with Reduce
Published in
6 min readAug 20, 2022
今天要練習的是,如何將 Playlists 內所有格式為「00:00」的影片時間加總,計算出總共的時間為幾時幾分幾秒。
學習重點
- NodeList 轉 Array :
[… ]
、Array.from()
- 資料處理,組成新陣列 :
.map()
- 分割字串 :
.split()
- 加總 :
.reduce()
- 無條件捨去小數,取整數 :
Math.floor()
- 餘數運算子: "%"
觀察範例檔案初始狀態
HTML
範例中預設有一個 videos 列表,裡面的<li>
項目都有 data-time
屬性,值為每段影片的時間。
<ul class="videos">
<li data-time="5:43">
Video 1
</li>
<li data-time="2:33">
Video 2
</li>
<li data-time="3:45">
Video 3
</li>
<li data-time="0:47">
Video 4
</li>
<li data-time="5:21">
Video 5
</li>
.
.
.</ul>
(最後完成的完整 JS 程式碼,以及檔案下載、課程連結,將放在最下方)
步驟拆解
- 取得 NodeList,並轉成 Array
- 取得每個節點內的
data-time
屬性值 - 取得分、秒,轉成數字,並計算成總秒數
- 將所有影片的秒數加總
- 將總秒數換算成 「時:分:秒」 格式
1. 取得 NodeList,並轉成 Array
- 抓取含有
data-time
屬性的所有節點,querySelectorAll
所取得的會是一個 NodeList。 - 利用
Array.from()
或[… ]
方法將 NodeList 轉為陣列。
2. 取得每個節點內的 data-time 屬性值
- 利用
.dataset.time
取得屬性值。 - 利用
.map()
方法將所有data-time
屬性值組成一個新的陣列。
利用 console.log
查看目前取得的資料狀態 :
3. 取得分、秒,轉成數字,並計算成總秒數
- 一樣使用
.map()
方法。 - 利用
.split(':')
來分割冒號兩邊的數字(字串)。 .map()
內可以直接呼叫 parseFloat 方法,便可將字串轉為數字。- 利用 ES6 解構附值寫法分別取得 分(mins), 秒(secs)。
- 在下方進行運算,將分鐘換算成秒數後加總,並作為返回值。
利用 console.log
查看目前取得的資料狀態 :
會得到每一個影片的總秒數,所組成的陣列
4. 將所有影片的秒數加總
- 利用
.reduce
方法將所有陣列內的秒數加總
利用 console.log
查看是否得到總秒數 :
5. 將總秒數換算成 「時:分:秒」 格式
- 將秒數除以 3600,換算成小時。利用
Math.floor()
取整數。 - 餘數運算子
%
可取得剩餘秒數。 - 分鐘數的算法與上述相似。
最後就能得到所有影片的總時間,為幾時幾分幾秒。
console.log
查看剛剛計算出來的 hours, mins, secondsLeft :
今天的練習就到這邊結束囉~
完整 JS 程式碼
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));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);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);
參考資料
範例檔案下載 :
JavaScript 30 課程註冊連結(輸入 email 免費註冊) :