본 시리즈는 인프런 강의 함수형 프로그래밍과 JavaScript ES6+ ( 지식 공유자 : 유인동 님 ) 의 강의를 수강하면서 내용을 제 방식대로 포스팅하는 글입니다.
reduce 는 값을 축약하는 함수이다.
이터러블 값을 하나의 값으로, 다른 값으로 축약해 나가는 함수다.
reduce 는 언제 사용할까?
// 이 값들을 모두다 더해서 하나의 값으로 만든다 할때
// reduce 를 사용하게 된다.
const nums = [1, 2, 3, 4, 5];
// 간단한 방법으로 이 로직을 구현해보자.
let total = 0;
// 특정 값을 순회하며 하나의 값으로 누적해 나갈때
// 이런 코드를 쓴다.
for (const n of nums) {
total = total + n;
}
log(total); // 15
이런 일을 할때 reduce 함수가 필요한데, 한번 직접 구현해서 해결해보도록 하자
// reduce 함수를 이해하기 위해 먼저 외부 인터페이스를 살펴보자
// 함수가 있다고 가정
const reduce = (any1 : any, any2: any, any3 : any) => {};
const add = (a: number, b: number) => a + b;
log(reduce(add, 0, [1,2,3,4,5])) // 이 결과가 15가 나오도록 하는 함수이다.
조금더 개념적으로 이해해보자
// 초기값으로 시작하고
log(add(add(add(add(add(0, 1), 2), 3), 4), 5)); // 15
// 연속적으로, 재귀적으로 받은 보조함수를 실행하면서 하나의 값으로 누적해나간다.
이제 보조함수를 받아 위임하는 함수를 만들면,
const nums = [1, 2, 3, 4, 5];
const add = (a: number, b: number) => a + b;
// acc : 누적값
const reduce = (fn: Function, acc: number, iter: Iterable<any>) => {
for (const a of iter) {
// 순회하는 행동을 보조함수에게 위임,
// 위의 코드랑 비교해보면, 더하는 연산을 하는 함수를 전달받아 위임.
acc = fn(acc, a);
}
// 외부 블록에 영향을 주는것이 아닌, 함수의 리턴값으로 반환
return acc;
};
log(reduce(add, 0, nums)); // 15
실제 JS 에선 acc 값이 없이도 작동할수 있도록 되어있는데, 그 부분을 작성해보자
// 이와같이 초기값이 없을때, JS 는 이터러블의 첫번째 값을 꺼내서
log(reduce(add, [1, 2, 3, 4, 5]));
// 아래와 같이 초기값을 생성한다.
log(reduce(add, 1, [ 2, 3, 4, 5]));
const nums = [1, 2, 3, 4, 5];
const add = (a: number, b: number) => a + b;
const reduce = (
fn: Function,
acc: number | Iterable<any>,
iter?: Iterable<any> | Iterator<any>
) => {
// 초기값이 없을때는, iter 인자에 전달된것이 없을것이다.
if (!iter) {
// acc 가 이터레이터 일것이다.
acc = acc as Iterable<any>;
// Symbol.iterator 를 실행해서 이터러블 값으로 변환시킨다.
iter = acc[Symbol.iterator]();
// acc 값은 이터러블 안의 첫번째 값이 되야하므로, next() 로 하나 꺼내서 할당해준다.
acc = iter.next().value;
}
for (const a of iter as Iterable<any>) {
acc = fn(acc, a);
}
return acc;
};
log(reduce(add, nums)); // 15
이렇게 되면, reduce 가 자바스크립트에 필요한 기능은 다 가지고 있게 된다.
'Javascript' 카테고리의 다른 글
map + filter + reduce 중첩 사용과 함수형 사고 - JS ES6+ 함수형 프로그래밍 - 17 (0) | 2022.09.27 |
---|---|
reduce 함수를 구현해보자 2 - JS ES6+ 함수형 프로그래밍 - 16 (0) | 2022.09.27 |
filter 함수를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 14 (1) | 2022.09.12 |
JS - 이터러블 프로토콜을 따른 map 의 다형성 (2) - JS ES6+ 함수형 프로그래밍 - 13 (2) | 2022.09.11 |
JS - 이터러블 프로토콜을 따른 map 의 다형성 (1) - JS ES6+ 함수형 프로그래밍 - 12 (0) | 2022.09.11 |