-
TIL.92 Javascript_Reduce 함수TIL/Javascript 2021. 1. 8. 23:41728x90
reduce()
배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.
reduce를 덧셈 함수이긴 하나 그 부분만 있는 것이아니다.
대부분의 사이트에서 reduce 사용 예시를 덧셈으로 들고 있기 때문이다.
하지만 reduce는 map과 함께 굉장히 중요하고 강력한 녀석으로 맵리듀스라는 프레임워크도 있을 정도이다.
배열.reduce((누적값, 현잿값, 인덱스, 요소) => { return 결과 }, 초깃값);
이전값이 아니라 누적값이라는 것에 주의하셔야 합니다.
누적값이기 때문에 다양하게 활용할 수 있습니다.
const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // expected output: 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // expected output: 15
덧셈 예제
초기값 X
const oneTwoThree = [1, 2, 3]; result = oneTwoThree.reduce((acc, cur, i) => {console.log(acc, cur, i);return acc + cur;}); // 1 2 1 3 3 2 console.log(result) // 6
초기값 O
acc(누적값)이 초깃값인 0부터 시작해서 return하는대로 누적되는 것을 볼 수 있습니다.
초깃값을 적어주지 않으면 자동으로 초깃값이 0번째 인덱스의 값이 됩니다.
const oneTwoThree = [1, 2, 3]; result = oneTwoThree.reduce((acc, cur, i) => {console.log(acc, cur, i);return acc + cur;}, 0); // 0 1 0 1 2 1 3 3 2 console.log(result) // 6
reduceRight
reduce와 동작은 같지만 요소 순회를 오른쪽에서부터 왼쪽으로 한다는 점이 차이
const oneTwoThree = [1, 2, 3]; result = oneTwoThree.reduceRight((acc, cur, i) => {console.log(acc, cur, i);return acc + cur;}, 0); // 0 3 2 3 2 1 5 1 0 console.log(result) // 6
초깃값을 활용하여 어떤 일을 할 수 있는지 알아보겠습니다.
map과 filter과 같은 함수형 메서드를 모두 reduce로 모두 구현할 수 있습니다.
map 예제를 reduce로 만들어보겠습니다.
초깃값을 배열로 만들고, 배열에 값들을 push하면 map과 같아집니다. 이를 응용하여 조건부로 push를 하면 filter와 같아집니다.
const oneTwoThree = [1, 2, 3]; result = oneTwoThree.reduce((acc, cur) => {acc.push(cur % 2 ? '홀수' : '짝수');return acc;}, []); console.log(result) // [ '홀수', '짝수', '홀수' ]
홀수만 필터링하는 코드
const oneTwoThree = [1, 2, 3]; result = oneTwoThree.reduce((acc, cur) => {if (cur % 2) acc.push(cur);return acc;}, []); console.log(result) // [ 1, 3 ]
이와 같이 sort, every, some, find, findIndex, includes도 다 reduce로 구현 가능합니다. reduce가 이들 모두의 아버지였던 것이다.
reduce는 비동기 프로그래밍을 할 때에도 유용합니다.
초깃값을 Promise.resolve()로 한 후에,
return된 프로미스에 then을 붙여 다음 누적값으로 넘기면 됩니다. 프로미스가 순차적으로 실행됨을 보장할 수 있습니다.
반복되는 모든 것에는 reduce를 쓸 수 있다는 것을 기억하시면 됩니다.
const promiseFactory = (time) => { return new Promise((resolve, reject) => { console.log(time); setTimeout(resolve, time); }); }; [1000, 2000, 3000, 4000].reduce((acc, cur) => { return acc.then(() => promiseFactory(cur)); }, Promise.resolve()); // 바로 1000 // 1초 후 2000 // 2초 후 3000 // 3초 후 4000
const promiseFactory = (time) => {return new Promise((resolve, reject) => {console.log(time); setTimeout(resolve, time);});};[1000, 2000, 3000, 4000].reduce((acc, cur) => {return acc.then(() => promiseFactory(cur));}, Promise.resolve());
728x90'TIL > Javascript' 카테고리의 다른 글
TIL.94 Javascript_Promise 이해하기 (0) 2021.01.10 TIL.93 Javascript 비동기 처리 이해하기 (0) 2021.01.09 TIL.89 Javascript_map 함수 (0) 2021.01.05