reduce는 함수형 프로그래밍을 공부하면, 항상 보게 되는 함수이다. 처음 reduce라는 함수를 마주쳤을 때, 굳이 이런 함수를 사용해야 하나, 이런생각도 해보기도 하고, 왜 감소하다라는 뜻을 갖고 있는 reduce이지? 이런생각을 해보기도 했다.
reduce는 reducer 함수에 의한 결과를 누적 해 주는 함수이다. 누적이라는 말에서 accumulate라고 불러야 하는거 아닌가? 하고 아직도 생각 하고 있는 함수이다.
reduce의 함수
reduce(
reducer: (accumulator: Any, current: Any) => Any,
initialValue: Any
) => accumulator: Any
javascript에는 Array가 이미 reduce를 지원을 하고 있기에, 아래와 같이 사용이 가능 하다.
[1, 2, 3].reduce(
(accumulator, current) => accumulator + current,
0)
// 6
구현을 해보자 한다면, 아래와 같이 간단하게 구현이 가능하다.
function reduce( arr, reducer, initValue ) {
let accumulator = initValue
for( let idx = 0; idx < arr.length; idx++ ) {
accumulator = reducer( accumulator, arr[idx], idx, arr )
}
return accumulator
}
Array.reduce와 마찬가지로 사용이 가능 하다.
reduce([1, 2, 3],
(accumulator, current) => accumulator + current,
0)
// 6
reduce로 만들어보기
reduce는 기본적으로 반복을 하기 때문에 forEach는 아래처럼 만들 수 있다.
const forEach = ( arr, fn ) => reduce( arr,(acc, item, index, arr) => {
fn(item, index, arr)
} )
filter함수는 reducer 연산결과를 배열에 담아 acc에 담아 주기만 하면 map이 된다.
const map = ( arr, fn ) => reduce( arr,(acc, item, index, arr) => {
acc.push( fn(item, index, arr) )
return acc
}, [] )
map([1, 2, 3], v => v * 2) // [2, 4, 6]
filter함수는 reducer 연산결과를 확인 하여, acc에 담아 주기만 하면 filter가 된다.
const filter = ( arr, fn ) => reduce( arr,(acc, item, index, arr) => {
fn(item, index, arr) && acc.push( item )
return acc
}, [] )
filter([1, 2, 3], v => v % 2 ) // [1, 3]
함수의 합성
지난 번에 만들어 보았던 pipe 함수도 reduce로 간단하게 만들 수 있게 되었다.
const pipe = (...fns) => x => reduce(fns, (v, f) => f(v), x)
const increase = v => v + 1
const double = v => v * 2
pipe( increase, double )( 3 ) // 8
당연하게도 반대로 실행이 가능하도록 만들어 볼 수도 있다.
const reverse = ( arr ) => reduce( arr,(acc, item) => {
acc.unshift( item )
return acc
}, [] )
const reduceRight = ( arr, ...args ) => {
const reverseArr = reverse(arr)
return reduce(reverseArr, ...args)
}
const compose = (...fns) => x => reduceRight(fns, (v, f) => f(v), x)
const increase = v => v + 1
const double = v => v * 2
compose( increase, double )( 3 ) // 7
간단하게 reverse함수와 reduceRight 함수를 정의 해주기만 하면 된다.
reduce는 다른 함수들과는 달리 이해하기가 꽤 까다로운 함수이다. 처음 접할 때에는 굳이 쓰려고 하지 않았지만, 위와 같이 다른 기능을 하는 함수를 만들 때 사용하기에는 다재다능한 함수이다.
댓글
댓글 쓰기