這一篇要來討論另一個跟 filter 很相似的方法 map,在我們討論 map 的同時,也可能會覺得怎麼好像在討論 filter,事實上確實這兩種方法差異真的不大,但為什麼 JavaScript 還是要分成兩種方法呢?其實他們最大的差異在於回傳的結果。
map 語法:
let new_array = arr.map(function callback( currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
以上 map 的解說,幾乎可以感覺就像是在看 filter,那這邊乾脆直接來做個差異分析好了。
map 和 filter 的相似之處在於:
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 來矯正與過濾。
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 可以進行數值的加總或是統計運算,傳統我們對於數值的加總會這麼寫:
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 則能夠對資料進行加總:
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 吧!