iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
0
Modern Web

一起挑戰 JavaScript 30 吧!系列 第 18

JS30 Day 18 - Adding Up Times with Reduce

  • 分享至 

  • xImage
  •  

頁面連結:Adding Up Times with Reduce(請開啟 console 看結果)、程式碼

今天同樣不會做出作品,重點是學習 reduce(..) --- 將 array 輸出成單一項目

可以從程式碼看到 HTML 中有許多 li,當中又有 data-time 的屬性,而今天的任務就是將所有 data-time 的所有時間相加並格式化成(時 分 秒)

那就開始吧!

首先先列出要做的事情

  • 取得 dataset 資料
  • 分別取得分&秒
  • 將分秒轉成 number 並相加
  • 加總時間
  • 格式化時間

取得 DOM

取得所有 li,但由於等一下會用到 array methods,所以要將 nodeList 轉成 array

const videos = Array.from(document.querySelectorAll('.videos li'));

取得 dataset 資料

還記得如何取得 dataset 資料嗎?就是 element.dataset.xxx

const seconds = videos
    .map(video => video.dataset.time)

// 此使得結果是一 array,每一項都是(分:秒)的 string

這樣寫法乍看很奇怪,目的是將所有方法串成一串,而不用宣告過多變數儲存

分別取得分&秒

dataset 中可以看到時間的格式都是(分:秒),我們可以利用 split()將分、秒分開

const seconds = videos
    .map(video => video.dataset.time)
    .map(time => time.split(':'))

將分秒轉成 number 並相加

接下來要加總每一項結果成秒數,但記得至此分、秒都還是 string,要轉成 number 才能相加

要將 string 轉成 number 我知道的方法有二

  • Number(..)
  • parseFloat(..)
const seconds = videos
    .map(video => video.dataset.time)
    .map(time => time.split(':'))
    .map(time => parseFloat(time[0]) * 60 + parseFloat(time[1]))

加總時間

這裡是重點啦!我們要用 reduce() 來加總每一項的秒數

reduce() 的 callback 最多可以傳入 4 個參數,分別是加總、當前值、當前 index、來源的 array,除了 callback 還可以傳入初始值(非必須)。但我們今天只會用到前兩個

const seconds = videos
    .map(video => video.dataset.time)
    .map(time => time.split(':'))
    .map(time => parseFloat(time[0]) * 60 + parseFloat(time[1]))
    .reduce((total, vidSeconds) => total + vidSeconds);

如果沒有給初始值的話,JS 預設會使用 array 第一項的值作為初始值

如此一來我們就有了總秒數了!剩下

格式化時間

這裡需要稍微想一下要如何用「秒數」得出時、分、秒

一分鐘等於 60 秒,利用餘數概念可以得出剩餘秒數

const second = seconds % 60;  // 1 分鐘 === 60 秒

% (mod)這個符號是運算餘數的意思,舉例來說 69 % 60; // 9

一小時等於 3600 秒,利用秒數除以 3600 可以得出小時,但由於不一定是整數,所以需要取整數(小數點後代表分、秒的加總)

const hour = Math.floor(seconds / 3600);

Math.floor(..) 的意思是無條件捨去法,四捨五入是 Math.round(..)、無條件進位法是 Math.ceil(..)

剛剛得出秒了,我們可以扣掉秒與時,剩下的就是分鐘數了

const minute = ((seconds - second) % 3600) / 60;

首先先減去秒數 -> 小時 + 剩餘分鐘 -> mod 小時(會得到剩餘秒數)-> 除以 60 就是分鐘數了~

最後印出結果就完成了!

console.log(hour, minute, second);
// 4 58 58

Reference


上一篇
JS30 Day 17 - Sort Without Articles
下一篇
JS30 Day 19 - Webcam Fun
系列文
一起挑戰 JavaScript 30 吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言