iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Modern Web

我的JavaScript日常系列 第 12

JavaScript Day 12. 每個元素都做運算的 map()

  • 分享至 

  • xImage
  •  

這一篇要來討論另一個跟 filter 很相似的方法 map,在我們討論 map 的同時,也可能會覺得怎麼好像在討論 filter,事實上確實這兩種方法差異真的不大,但為什麼 JavaScript 還是要分成兩種方法呢?其實他們最大的差異在於回傳的結果。

map 語法:

let new_array = arr.map(function callback( currentValue[, index[, array]]) {
    // return element for new_array
}[, thisArg])
  • callback / 是一個函數,用來產生新陣列的元素。新數值會在每次執行 callback 時加到 new_array,並且此函數可傳入三個參數:
    1. currentValue 代表目前處理到的元素的值。
    2. index 代表目前處理到的元素的索引位置。
    3. array 代表陣列本身。
  • 根據 callback 的執行結果,回傳 true 表示測試通過;回傳 false 則表示失敗。
  • thisArg 代表 callback 裡面的 this 是指向哪一個物件。
  • map 執行的結果與 filter 一樣會回傳一個新陣列。

以上 map 的解說,幾乎可以感覺就像是在看 filter,那這邊乾脆直接來做個差異分析好了。

map 和 filter 的相似之處在於:

  • 皆為 JavaScript 的陣列方法。
  • 都不會影響到原來的陣列,而是會回傳一個新的陣列。
  • 都是透過 callback 函式來處理陣列中的元素,函式參數可帶入「目前正在處理的元素 (currentValue)」、「正在處理的元素索引 (index)」、「原始陣列 (array)」。

map 與 filter 最大的差異在於,filter 產生的新陣列只包含「符合回傳條件」的元素,map 則是會包含「運算後」的所有元素。

上一篇 filter 的範例可以看到,filter 回傳的是「判斷為 true 的元素」,而底下 map 陣列回傳的是「元素的運算結果」。這邊要注意的是,map 一定會替原始陣列的每個元素回傳一個值,如果沒有值則會回傳 undefined。

let a = [1,2,3,4];
mapEmpty = a.map(function(num){
    return num * 2;
});
console.log(mapEmpty); // [2, 4, 6, 8]

map 對資料的矯正與處理

我們已經知道 map 的原理,接下來可以開始討論,除了上面我們所知道的操作以外,map 究竟還可以做些什麼事?map 還可以針對資料進行過濾或矯正,舉例來說我們獲得一組資料,裡面包含很多數值,現在我們希望這些數值不要超過我們設定的上限,這時便可以使用 map 來矯正與過濾。

let arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

let newArr = arr.map(function(element) {
    // 數值大於 2 的數值視為 4
    if (element > 2)
        return 4;
        
    return element;
});

console.log(newArr); // [1, 2, 4, 4, 4, 4, 4, 4, 4, 4]

在查找資料的過程,也看見了一個自己之前沒有遇過的方法,也覺得這個方法能夠在某些實務上獲得不少的提升,因此我也放在這裡討論。

reduce

reduce 可以進行數值的加總或是統計運算,傳統我們對於數值的加總會這麼寫:

let arr = [ 4, 5, 6 ];
let result = 0;

for (let index in arr) {
    result += arr[index];
}

console.log(result); // 15

但如果我們使用 reduce,可以看到元素的加總計算,不會再需要去存取到外層的 result,而是算完以後才把結果回傳,這部分我理解是,所有的工作都在內層完成,不會去污染到外部。

let arr = [ 4, 5, 6 ];

// 處理每個元素後等待回傳結果,第一次處理時代入初始值 0
let result = arr.reduce(function(prev, element) {
    // 與之前的數值加總,回傳後代入下一輪的處理
    return prev + element;
}, 0);

console.log(result); // 15

map 與 reduce

這兩種方法都適用陣列處理,因此也可以一起使用,map 可以對陣列資料進行矯正,reduce 則能夠對資料進行加總:

let arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

let result = arr
    .map(function(element) {
        // 數值大於 2 的數值視為 4
        if (element > 2)
            return 4;
            
        return element;
    })
    .reduce(function(prev, element) {
        // 與之前的數值加總,回傳後代入下一輪的處理
        return prev + element;
    }, 0);

console.log(result); // 35

誤打誤撞遇到 reduce 這個方法,其實覺得蠻好用的,關於它的使用方式或許可以再做一篇文章來討論,這裡就不放太多搶走 map 的光環啦~

參考資料:
JavaScript 陣列處理方法
上手使用 JavaScript 的 Map、Reduce 吧!


上一篇
JavaScript Day 11. 篩選條件 filter()
下一篇
JavaScript Day 13. forEach()
系列文
我的JavaScript日常31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言