# Functional iteration
* A function is passed as an argument to the higher-order function, which then calls this function during the iteration process.
* Functional iteration is typically immutable, meaning that it does not modify the original data structure but returns a new one instead.
* This approach offers advantages such as simplicity, high readability, and the ability to process various types of data, such as arrays, sets, maps, and others.
Common methods for functional iteration include map(), reduce(), filter(), forEach(), and others.
---
### From for Loop to forEach


### Identify Before, Body, and After
```javascript!
function emailsForCustomers(customers, goods, bests) {
// Before: Initialize the 'emails' variable as an empty array.
var emails = [];
// Body: Use the 'forEach' method to iterate over the 'customers' array and pass each element to the 'emailForCustomer()' function.
for(var i = 0; i < customers.length; i++) {
var customer = customers[i]
var email = emailForCustomer(customer, goods, bests);
emails.push(email);
}
// After: Return the new 'emails' array that contains all email addresses.
return emails;
}
```
### Extract function & callback

The extracted function allows for reuse of Before and After, while Body becomes a callback, providing greater flexibility and maintaining copy-and-write.
### map()


* Map() is only responsible for iterating over each value, but does not guarantee a return value. (null or undefined)
### filter()
* Since filter includes a conditional statement, it can be used to filter out the desired values
The method for identifying Before, Body, and After is the same, except that Body in this case refers to the conditional statement



### reduce()
The method for identifying Before, Body, and After is the same, except that Body in this case refers to the computation



#### Tings you can do with reduce()
* Undo/redo
```javascript!
const actions = [
{ type: "add", value: "A" },
{ type: "add", value: "B" },
{ type: "remove" },
{ type: "add", value: "C" },
];
function applyActions(actions) {
return actions.reduce((result, action) => {
if (action.type === "add") {
return result.concat(action.value);
} else if (action.type === "remove") {
return result.slice(0, -1);
} else {
return result;
}
}, "");
}
// get AC
```
* Replaying user interaction for testing
Think about it: If your initial value is the initial state of the sys- tem, and your array is a sequence of user interactions, reduce() can combine all of those into a single value—which will be the current state.
假設我們正在開發一個簡單的計算機應用程序,用戶可以在應用程序中輸入數字和操作符,進行加、減、乘、除等運算。我們可以將每個用戶操作都表示為一個函數,接受一個當前狀態,返回一個新的狀態。然後,我們可以使用 reduce 方法將這些操作應用到初始狀態中,得到最終的狀態,這個狀態就代表了應用程序中的當前狀態。如果我們想要測試這個應用程序,只需將這些用戶操作表示為一個陣列,然後使用 reduce 方法來重現這些操作,得到最終的狀態,這個最終狀態就可以用於驗證應用程序的正確性。這種方法可以有效地測試應用程序的交互行為,並幫助我們捕捉應用程序中可能存在的錯誤和問題。
* Time-traveling debugger
Some languages will let you replay all of the changes up to a point. If something is behaving incorrectly, you can back up and exam- ine the state at any point in time, fix the problem, then play it forward with the new code. It sounds like magic, but it’s enabled by reduce().
具體來說,如果我們將系統的狀態表示為一個陣列,每個元素都是系統在某個時間點的狀態,我們就可以使用 reduce 方法將這些狀態組合成一個單一的值,這個值就是當前系統的狀態。如果我們想要進行除錯,只需使用 slice 方法從這個陣列中選擇一段時間範圍內的狀態,然後使用 reduce 方法將這些狀態應用到初始狀態中,得到當前時間點的狀態。這個狀態就可以用於進行除錯,找出系統中的問題所在。如果我們發現了問題,只需修復問題,然後重新應用剩餘的狀態,就可以將系統恢復到正常狀態。
這種時間旅行式的除錯功能非常強大,可以幫助開發人員快速發現並解決系統中的問題,提高開發效率和品質。
* Audit trails
Sometimes you want to know the state of the system at a certain point in time, like when the legal department calls you to ask “What did we know as of December 31?”reduce()enables you to record the history so you’ll not only know where you are, but also how you got there.
具體來說,如果我們將系統的狀態表示為一個陣列,每個元素都是系統在某個時間點的狀態,我們就可以使用 reduce 方法將這些狀態組合成一個單一的值,這個值就是當前系統的狀態。同時,我們還可以將這個陣列保存下來,作為系統的歷史紀錄(audit trail)。這樣,當需要查詢系統在某個時間點的狀態時,我們只需使用 slice 方法從這個陣列中選擇一段時間範圍內的狀態,然後使用 reduce 方法將這些狀態應用到初始狀態中,得到當前時間點的狀態。同時,我們還可以通過查詢歷史紀錄(audit trail)來了解系統在不同時間點的狀態,以及系統是如何從一個狀態轉移到另一個狀態的。