iT邦幫忙

1

JS30 Day 18 - Adding Up Times with Reduce學習筆記

這次的主題主要是利用reduce將時間做一個總和,並計算出時分秒。

https://ithelp.ithome.com.tw/upload/images/20200715/201261824s2pex5Mn5.png

首先獲取我們全部的li,並轉為陣列型式。


  let li = Array.from(document.querySelectorAll('li'));

split: 分割字串成字串組,且不會改變原值 stringObject.split(separator,howmany)

separator 字串符或正則表達式,從該參數指定的地方分割stringObject。
howmany 返回值的最大長度,超過該長度則不顯示。

reduce: Array.prototype.reduce( callback < accumulator, currentValue, currentIndex, array >, initialValue ) 每次 return 的內容都會存到 accumulator 中,因此可以累加陣列裡的內容後回傳。

在JS DAY30中的DAY4有提到 https://ithelp.ithome.com.tw/articles/10231275


var str="How are you ?"
var splits1 = str.split(" ");
var splits2 = str.split("");
var splits3 = str.split(" ",3);

//splits1 ["How", "are", "you", "?"]
//splits2 ["H", "o", "w", " ", "a", "r", "e", " ", "y", "o", "u", " ", "?"]
//splits3 ["How", "are", "you"]

利用map將資料(自定義屬性為time的li)拆分出來,再進行一次map,並利用split將time拆分出來成分及秒,並賦予至解構中的同時也順便命了名,而後我們將拆分出來的分秒都化為秒(因為分秒皆為string,故要轉成number)並計算個別分秒的總秒數,最後再利用reduce做全部秒數的總和。


  const result = li.map(item => item.dataset.time)
        .map(time => {
        
          // 將分秒利用split拆開,並利用解構直接命名,且將分秒傳入
          let [min, sec] = time.split(":");
          
          // console.log([min, sec]);
          // ["5", "43"], ["2", "33"] ...
          
          // 算出總秒數
          // 利用*1強制轉型別(原本是字串)
          // return min * 60 + sec * 1;
          
          // 或是直接parseInt轉整數
          return min * 60 + parseInt(sec);
        })
        // ((前一個數值,下一個數值),起始值)
        .reduce((prev, next) => {
          // 秒數做加總
          return prev + next
        }, 0)

最後,將我們處理完的總秒數,劃分為時分秒即可。


 // 將總秒數拆分成 時分秒
 
      let sec = result % 60;
      
      // let min = (result - sec) / 60;
      // let min = Math.floor(result / 60) % 60;
      
      let min = Math.floor(result / 60)
      
      // let hour = Math.floor(result / 60 / 60);
      let hour = Math.floor(min / 60);
      
      min %= 60;
      
      console.log(hour, min, sec); // 4 58 58

如何用foreach達到break的效果?

這邊額外學到一個觀念,也順便來分享一下,不利用for而用foreach來做break,當跑第一次時,資料及array不變,皆為正常,當資料為2,進入array.concat.....,先利用splice將array刪減,此時下標為1所以從(1,4)的下標資料都給刪減[2,3,4,5],所以剩下[1],但此時foreach已經因為陣列長度產生變化而停止,最後利用concat將ary合併至原本陣列,因此我們得到的array與原本不變,既可達到break又不會改變原陣列

更多作法可參考:
https://jser.me/2014/04/02/%E5%A6%82%E4%BD%95%E5%9C%A8Array.forEach%E7%9A%84%E5%BE%AA%E7%8E%AF%E9%87%8Cbreak.html


      var array = [1, 2, 3, 4, 5];
      array.forEach(function (item, index, ary) {
        if (item === 2) {
         array = ary.concat(ary.splice(index, ary.length - index));
        }
        console.log(item); //只输出1,2
        console.log(ary);
        console.log(array);
      });
      console.log(array);


尚未有邦友留言

立即登入留言