-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# 12장 - 함수형 반복 | ||
|
||
## 이번 장에서 살펴볼 내용 | ||
|
||
- 함수형 도구 map, filter, reduce 에 대해 | ||
- 배열에 대한 반복문을 함수형 도구로 바꾸는 방법 | ||
- 함수형 도구를 어떻게 구현하는지 | ||
|
||
## 함수형 도구 map() | ||
|
||
```jsx | ||
// 기존 코드 for문을 함수형 도구를 통해 바꿔보자 | ||
function emailsForCustomers(customers, goods, bests){ | ||
let emails = []; | ||
for(let i = 0; i < costomers.length ; i ++){ | ||
let customer = customers[i]; | ||
let email = emailForCustomer(customer, goods, bests) | ||
emails.push(email); | ||
} | ||
return email; | ||
} | ||
|
||
// for문 => forEach() | ||
// 기존 코드애서 불필요한 중복을 많이 없앰 | ||
function emailsForCustomers(customers, goods, bests){ | ||
let emails = []; | ||
forEach(customers, function(customer){ | ||
let email = emailForCustomer(customer, goods, bests) | ||
emails.push(email); | ||
}); | ||
return emails; | ||
} | ||
|
||
// forEach() => map() | ||
function emailsForCustomers(customers, goods, bests){ | ||
return map(customers, function(customer){ // 고객 배열을 map()에 전달 | ||
return emailForCustomer(customer, goods, bests); | ||
}); | ||
} | ||
``` | ||
|
||
여담인데 lodash.map 과 es6 map 의 성능 비교를 했을 때 es6 map 이 훨씬 좋다는 성능 결과가 나온다. (map 말고도 filter, some, find 등 다른 메서드들을 비교했을 때도 동일한 결과) | ||
|
||
## filter | ||
|
||
위 고객 배열에서 goods가 없는 고객이 있다면 null이나 undefined 가 나올것이다. | ||
|
||
map은 배열 전체에 함수를 적용하기 때문에 항목에 대한 조건식을 통해 걸러낼 수 있는 기능이 필요하다. | ||
|
||
```jsx | ||
function filter(array, f){ | ||
let newArray = []; | ||
forEach(array, function(element){ | ||
if(f(element)) | ||
newArray.push(element); | ||
}); | ||
return newArray; | ||
} | ||
``` | ||
|
||
## reduce | ||
|
||
```jsx | ||
function reduce(array, init, f){ | ||
let accum = init; // 누적된 값 초기화 | ||
forEach(array, function(element){ | ||
accum = f(accum,element) // 누적 값을 계산하기 위해 현재 값과 배열 항목으로 f() 함수 호출 | ||
}); | ||
return accum; // 누적된 값 리턴 | ||
} | ||
``` | ||
|
||
## **reduce로 할 수 있는 것들** | ||
|
||
reduce는 매우 강력함. 실무에서도 많이 쓰임. | ||
|
||
reduce()로 filter()나 map()도 만들 수 있다. 하지만 그 반대는 불가능 | ||
|
||
### **실행 취소 / 실행 복귀** | ||
|
||
실행 취소와 복귀는 제대로 동작하게 만들기가 매우 어렵다. | ||
|
||
리스트 형태의 사용자 입력에 reduce()를 적용한 것이 현재 상태라고 생각해보면, 실행 취소는 리스트 의 마지막 사용자 입력을 없애는 것이라고 할 수 있다. | ||
|
||
### **테스트할 때 사용자 입력을 다시 실행하기** | ||
|
||
시스템의 처음 상태가 초깃값이고 사용자 입력이 순서대로 리스트에 있을 때 reduce()로 모든 값을 합쳐 현재 상태를 만들 수 있다. | ||
|
||
### **시간 여행 디버깅** | ||
|
||
어떤 언어는 변경 사항을 어떤 시점으로 되돌릴 수 있다. | ||
|
||
뭔가 잘못 동작하는 경우 특정 시점 상태의 값을 보관할 수 있다. | ||
|
||
그리고 문제를 해결하고 새로운 코드로 다시 실행해볼 수 있다. | ||
|
||
reduce()를 통해서 가능하다. | ||
|
||
### **회계 감사 추적** | ||
|
||
특정 시점에 시스템 상태를 알고 싶은 경우 | ||
|
||
reduce()로 과거에 어떤 일이 있었는지 기록할 수 있다. | ||
|
||
어떤 일이 있었는지 뿐만 아니라 어떤 과정을 통해 일이 생겼는지도 알 수 있다. | ||
|
||
⇒ reduce로 로그를 쌓고 과거의 값을 변경할 수 있어서 유용하게 쓰인다 |