新手村18 - Adding Up Times with Reduce

18 - Adding Up Times with Reduce

俗話說的好,一天一蘋果,醫生遠離我

一天一 JS,What the f*ck JavaScript?

small steps every day - 記錄著新手村日記

完成目標

透過 Reduce 把播放清單中的時間加起來。

  • 功能

    加總時間

  • 畫面

    依時間格式顯示小時、分鐘、秒數

index_START.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Videos</title>
</head>
<body>
<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>
<li data-time="6:56">
Video 6
</li>
<li data-time="3:46">
Video 7
</li>
<li data-time="5:25">
Video 8
</li>
<li data-time="3:14">
Video 9
</li>
<li data-time="3:31">
Video 10
</li>
<li data-time="5:59">
Video 11
</li>
<li data-time="3:07">
Video 12
</li>
<li data-time="11:29">
Video 13
</li>
<li data-time="8:57">
Video 14
</li>
<li data-time="5:49">
Video 15
</li>
<li data-time="5:52">
Video 16
</li>
<li data-time="5:50">
Video 17
</li>
<li data-time="9:13">
Video 18
</li>
<li data-time="11:51">
Video 19
</li>
<li data-time="7:58">
Video 20
</li>
<li data-time="4:40">
Video 21
</li>
<li data-time="4:45">
Video 22
</li>
<li data-time="6:46">
Video 23
</li>
<li data-time="7:24">
Video 24
</li>
<li data-time="7:12">
Video 25
</li>
<li data-time="5:23">
Video 26
</li>
<li data-time="3:34">
Video 27
</li>
<li data-time="8:22">
Video 28
</li>
<li data-time="5:17">
Video 29
</li>
<li data-time="3:10">
Video 30
</li>
<li data-time="4:43">
Video 31
</li>
<li data-time="19:43">
Video 32
</li>
<li data-time="0:47">
Video 33
</li>
<li data-time="0:47">
Video 34
</li>
<li data-time="3:14">
Video 35
</li>
<li data-time="3:59">
Video 36
</li>
<li data-time="2:43">
Video 37
</li>
<li data-time="4:17">
Video 38
</li>
<li data-time="6:56">
Video 39
</li>
<li data-time="3:05">
Video 40
</li>
<li data-time="2:06">
Video 41
</li>
<li data-time="1:59">
Video 42
</li>
<li data-time="1:49">
Video 43
</li>
<li data-time="3:36">
Video 44
</li>
<li data-time="7:10">
Video 45
</li>
<li data-time="3:44">
Video 46
</li>
<li data-time="3:44">
Video 47
</li>
<li data-time="4:36">
Video 48
</li>
<li data-time="3:16">
Video 49
</li>
<li data-time="1:10">
Video 50
</li>
<li data-time="6:10">
Video 51
</li>
<li data-time="2:14">
Video 52
</li>
<li data-time="3:44">
Video 53
</li>
<li data-time="5:05">
Video 54
</li>
<li data-time="6:03">
Video 55
</li>
<li data-time="12:39">
Video 56
</li>
<li data-time="1:56">
Video 57
</li>
<li data-time="4:04">
Video 58
</li>
</ul>
<script>
</script>
</body>
</html>

JS - step by step

首先,先透過 querySelectorAll 抓出所有的 li,方便我們之後透過 reduce 方法來計算裡面的時間,還記得前面幾張所說,透過這個方法抓出的數值會是一個 Nodelist,因此如果要轉成陣列的話有以下四種方法:

1
2
3
4
5
6
7
8
9
10
<script>
let li = document.querySelectorAll("li");
let a = Array.from(li).map( item => item);
let b = [].map.call(li, item => item);
let c = [].map.apply(li, [item => item]);
let d = [...li].map( item => item);

//(58) [li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li]

</script>

接下來,必須透過 dataset.time 來抓出 lidata-time 的值

HTMLElement.dataset:https://tinyurl.com/yywtglmc

1
2
3
4
5
6
7
8
9
10
<script>
let li = document.querySelectorAll("li");
// let a = Array.from(li).map( item => item);
// let b = [].map.call(li, item => item);
// let c = [].map.apply(li, [item => item]);
let d = [...li].map( item => item.dataset.time);
console.log(d);

//(58) ["5:43", "2:33", "3:45", "0:47", "5:21", "6:56", "3:46", "5:25", "3:14", "3:31", "5:59", "3:07", "11:29", "8:57", "5:49", "5:52", "5:50", "9:13", "11:51", "7:58", "4:40", "4:45", "6:46", "7:24", "7:12", "5:23", "3:34", "8:22", "5:17", "3:10", "4:43", "19:43", "0:47", "0:47", "3:14", "3:59", "2:43", "4:17", "6:56", "3:05", "2:06", "1:59", "1:49", "3:36", "7:10", "3:44", "3:44", "4:36", "3:16", "1:10", "6:10", "2:14", "3:44", "5:05", "6:03", "12:39", "1:56", "4:04"]
</script>

印出時間後,我們必須抓出分鐘、秒數,並命名為 [min,sec],記得考慮到字串、數字的問題,不管是分鐘或者是秒數都必須乘上數字!

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let li = document.querySelectorAll("li");
// let a = Array.from(li).map( item => item);
// let b = [].map.call(li, item => item);
// let c = [].map.apply(li, [item => item]);
let d = [...li].map( item => item.dataset.time)
.map( time => {
let [min,sec] = time.split(":");
return min * 60 + sec * 1 ;
});
console.log(d);
//(58) [343, 153, 225, 47, 321, 416, 226, 325, 194, 211, 359, 187, 689, 537, 349, 352, 350, 553, 711, 478, 280, 285, 406, 444, 432, 323, 214, 502, 317, 190, 283, 1183, 47, 47, 194, 239, 163, 257, 416, 185, 126, 119, 109, 216, 430, 224, 224, 276, 196, 70, 370, 134, 224, 305, 363, 759, 116, 244]
</script>

這時候就要用上 reduce 將剛剛所有的時間加總起來,

Array.prototype.reduce():https://tinyurl.com/yye5lgcw

1
2
3
4
5
6
7
8
9
10
11
12
<script>
let li = document.querySelectorAll("li");
// let a = Array.from(li).map( item => item);
// let b = [].map.call(li, item => item);
// let c = [].map.apply(li, [item => item]);
let d = [...li].map( item => item.dataset.time)
.map( time => {
let [min,sec] = time.split(":");
return min * 60 + sec * 1 ;
}).reduce( (first,next) => first + next , 0);
console.log(d);
</script>

最後再將所有的時間算數算出小時、分鐘、秒鐘~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
let li = document.querySelectorAll("li");
// let a = Array.from(li).map( item => item);
// let b = [].map.call(li, item => item);
// let c = [].map.apply(li, [item => item]);
let d = [...li].map( item => item.dataset.time)
.map( time => {
let [min,sec] = time.split(":");
return min * 60 + sec * 1 ;
}).reduce( (first,next) => first + next , 0);
console.log(d);

let sec = d % 60;
let min = (d - sec) / 60;
let hour = Math.floor(min / 60);

min %= 60;
console.log(`${hour}:${min}:${sec}`);
</script>

就大功告成啦!

JS - final

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>

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);

</script>

本刊同步於個人網站:http://chestertang.site/

本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n