Array
의 대표 메서드들인 map
, filter
, reduce
삼총사 중에 마지막 녀석인 reduce
를 직접 구현해 보도록 할게요.
참고로 이번 글에는 iterator
개념이 살짝 들어가 있으니 이 개념에 익숙치 않으신 분들은 MDN문서 - iterator protocol 나, 저의 이전 글 - iterable 과 iterator을 읽어보고 오시면 도움이 되실거에요.
map
과 filter
에 비해서 reduce
는 고려해야 할게 아주 조금 더 있는데요,
함수에 필요한 기능들부터 정의하고 시작하겠습니다.
reduce
함수 스펙
- 인자 3개를 받는다. 각각의 인자는 predicate(사용자 정의 연산에 쓰일 함수), iter(iterable), acc(연산 결과를 누적시켜 나갈 값) 이다. 만약 3번째 인자인
acc
가 없다면 2번째 인자인iter
의 첫 번째 요소를 acc 의 초깃값으로 설정한다.- iter 에서 item 을 하나씩 가져와서 predicate 함수로 연산을 한 결과를 acc 에 누적시킨다.
위에서 정의한 대로 구현을 해보겠습니다.
function reduce(predicate, iter, acc) {
if (acc === undefined) {
// 3번째 인자인 acc 인자가 주어지지 않은 경우
// 2번째 인자인 iter의 첫 번째 값을 초기 값으로 세팅한다.
const iterator = iter[Symbol.iterator]()
acc = iterator.next().value
}
// iter 를 순회하면서 각 item 과 acc 값에 대한 연산 결과를 acc 에 누적시켜 나간다.
for (const item of iter) {
acc = predicate(item, acc)
}
return acc
}
구현을 마쳤으니, 이제 함수가 올바르게 동작하는지 테스트 해볼게요!
const totalSum = reduce((num, acc) => num + acc, [1, 2, 3, 4, 5], 0)
const totalMul = reduce((num, acc) => num * acc, [1, 2, 3, 4, 5], 1)
console.log(totalSum) // 15
console.log(totalMul) // 120
원하는 대로 함수가 잘 동작하네요!