擁抱Reduce、ForEach、Filter、Map
這些函式怎麼協助我替代 for 迴圈?
先把每個函式清楚說一遍,這樣你知道哪些函式可以用來替代什麼時機的 for 迴圈了。
- forEach:遍歷每個元素。
- map:遍歷每個元素,回傳的值會替代原本陣列內的值。
- filter:遍歷每個元素,回傳 true 時,目前的值會保留在陣列內,這會回傳一個新陣列,而不是修改原本的陣列。
- reduce:遍歷每個元素,依序組合、加總,然後丟給下個元素,最終會回傳一個結果。
如果你還是不清楚的話,沒關係,下面都有範例,畢竟沒看到範例之前你可能還是不知道那個奇怪的 reduce 是什麼東西。
ForEach
如果你沒有打算要修改陣列的內容,你只是希望遍歷陣列內的每個元素,那麼你就可以使用 forEach 函式。在傳統 for 迴圈你會這麼做。
var arr = [1, 2, 3];
for(var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
接著讓我們透過 forEach 並搭配 () => {} 來讓你的程式更加簡短但是達到跟上面相同效果。
var arr = [1, 2, 3];
arr.forEach((val) => {
console.log(arr[i]);
})
如果你不知道 () => {} 是什麼,它實際上就是 ES6 推出的函式簡寫,也就是 function() {} 的縮寫(雖然有點不同,但就不提了)。
Map
如果你希望遍歷陣列內的每個內容,然後修改原始陣列,那麼 map 就是你的好夥伴。先看看以往的做法是如何。
var arr = [1, 2, 3],
newArr = [];
for(var i = 0; i < arr.length; i++) {
newArr[i] = arr[i] * 2;
}
console.log(newArr); // [2, 4, 6]
接著透過 map 你的程式可以短個至少 40% 以上。
var arr = [1, 2, 3];
arr.map((val) => {
return val * 2;
})
console.log(arr); // [2, 4, 6]
Filter
這個按照字面上的意思來說就是過濾器,filter 不會修改值,但他會幫你決定要不要將這個值留在陣列裡面,要注意的是 filter 會回傳一個新的陣列,而不是修改原本的陣列。
var arr = [1, 2, 3, 4],
newArr = [];
for(var i = 0; i < arr.length; i++) {
if(arr[i] > 2) {
newArr.push(arr[i]);
}
}
console.log(newArr); // [3, 4]
透過 filter,在遍歷陣列內容的同時,你可以回傳布林值來決定要不要將這個值留在陣列內。
var arr = [1, 2, 3, 4];
var newArr = arr.filter((val) => {
return val > 2;
})
console.log(newArr); // [3, 4]
Reduce
如果你希望把陣列內的內容作加總並最終回傳一個結果,那麼你就可以用上 reduce。這個使用的機率應該不高,但是要將陣列內的內容全部統整的時候應該很好用。
var arr = [1, 2, 3],
totalNum = 0;
for(var i = 0; i < arr.length; i++) {
total += arr[i];
}
console.log(totalNum); // 6
接著透過 reduce 你就可以直接取得加總的結果。
var arr = [1, 2, 3];
var totalNum = arr.reduce((total, val) => {
return total + val;
}, 0);
console.log(totalNum); // 6
在上述的 reduce 中的第二個參數為 0 即是將 total 初始化成 0,就像我們在傳統程式中定義 var totalNum = 0; 一樣。然後我們會取得每個元素的值,對 total 進行加總,最終 reduce 就會回傳這個值。