iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

前端藏寶圖系列 第 3

就決定是你了 - 陣列系列I

圖片來源:tooto1985/js-array-operations

內心劇場之胡言亂語

萬能又好用的迴圈之於前端開發者,就好比皮卡丘之於小智,那麼不可或缺。
BUT!!!為了挑戰更強的道館,必須要有其他的神奇寶貝啊~
為了從JS幼幼班畢業,必須要學會功能齊全又語意明確的陣列方法啊~

系列I來學習怎麼使用不會改變原陣列的Array Method吧!

使用目的 方法名稱 回傳值
用膩了for迴圈 Array.prototype.forEach() undefined
想建立一個新陣列,且需要對原陣列的元素做處理 Array.prototype.map() 回呼函式回傳結果所組成的新陣列
需要產生符合特定條件的新陣列 Array.prototype.filter() 通過回呼函式檢驗的新陣列
加總資料/轉換資料格式 Array.prototype.reduce() 運算結果/整理後的資料
  • 上述每個方法的括弧中都可以放入一個callback function,且可以傳入三個參數,依序是

    1. 目前迭代處理的元素
    2. 目前迭代處理的元素的索引值
    3. 呼叫該方法的陣列
  • reduce的callback function參數跟其他三者不同,依序是

    1. 累加器
    2. 目前迭代處理的元素
    3. 目前迭代處理的元素的索引值
    4. 呼叫該方法的陣列

以下用Wes Bos 的Javascript 30: Array Cardio 做為範例來特訓

  • 要處理的資料是一個取名叫inventors的陣列,陣列每個元素是一個物件,物件中裝有發明家的姓名和生卒年資料。
const inventors = [
      { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
      { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
      { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
      { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
      { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
      { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
      { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
      { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
      { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
      { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
      { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
      { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
    ];

關卡1: 從資料撈出發明家的全名

// 使用for-loop 

const fullNameList = [];
for (let index = 0; index < inventors.length; index++) {
    const fullName = inventors[index].first + ' ' + inventors[index].last;
    fullNameList.push(fullName);
};

console.log(fullNameList);
// 使用array method

const fullName = inventors.map( inventor => inventor.first + ' ' + inventor.last);

比較兩者可以發現陣列方法讓程式碼更簡潔

  1. 不用建立儲存資料的空陣列,因為map的回傳值就是一個新的陣列
  2. 不用寫for-loop裡頭的初始值,終止條件和迭代值
  3. 不需要把資料push到建立的空陣列裡頭
  4. 減少命名的困擾

關卡2: 撈出在16世紀(1500~1599)出生的發明家

// 使用for-loop
const inventorBornIn1500s = []; -> 代表需要新陣列

inventors.forEach(inventor => {
    // 代表資料需要符合特定條件才放入新陣列中
    if (inventor.year >= 1500 && inventor.year < 1600) {
        inventorBornIn1500s.push(inventor);
    };
});
// 使用array method

const inventorBornIn1500s = inventors.filter( inventor => 1500 <= inventor.year && inventor.year < 1600);

觀察心得:

  1. 用條件式判斷了要撈出的資料
  2. 建立了空陣列要裝撈出的資料
  3. 符合上述兩點的話,可以派出filter方法應戰喔

關卡3: 計算資料中所有發明家在世的時間總和

const result = inventors.reduce((totalYears, inventor) => {
    const yearsLived = inventor.passed - inventor.year
    return totalYears + yearsLived
}, 0); 

// 這裡的累加器命名作totalYears
// 0 是指定的初始值

使用reduce要注意的小地方:

  1. 記得回傳累加器,否則結果會出現undefined
  2. 沒有設定初始值,就會以陣列第一個元素作為累加器

今日特訓到此結束,如果腦袋出現陣列方法排斥反應的話,沒關係的,至少我們還有迴圈皮卡丘可以依靠。
明天記得繼續來特訓喔~/images/emoticon/emoticon76.gif


參考資料及學習資源:

JAVASCRIPT 30
Array Methods - MDN


上一篇
岔路上的風景 - 遞迴
下一篇
就決定是你了 - 陣列系列 II
系列文
前端藏寶圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Chris
iT邦新手 4 級 ‧ 2021-09-18 12:27:59

加油喔

Chiahsuan iT邦新手 4 級 ‧ 2021-09-18 14:25:15 檢舉

/images/emoticon/emoticon41.gif
你也加油喔!!!!

0
Teen
iT邦新手 5 級 ‧ 2021-09-19 11:30:54

內心小劇場好激昂啊~/images/emoticon/emoticon37.gif

Chiahsuan iT邦新手 4 級 ‧ 2021-09-19 12:20:57 檢舉

/images/emoticon/emoticon07.gif
表面風平浪靜,內心波濤洶湧XDDD

我要留言

立即登入留言