TIL

Yun Subin·2022년 10월 9일
0

BEB_07_RK_NFT

목록 보기
8/10

reduce 활용하기

함수형 프로그래밍

많은 분들이 forEach는 사용하시는데 map과 reduce는 잘 안 쓰시더라고요.
그리고 reduce가 뭐냐고 물어보면 덧셈하는 함수 아니냐고 하시는 분도 많이 봤습니다.
ㅠㅠ 그래서 오늘은 제가 제일 좋아하는 메서드인 map과 reduce에 대해 알아보겠습니다.
제가 생각하기로는 자바스크립트 내장 메서드 중에서 제일 강력하고,
알아두면 다양한 곳에 활용할 수 있는 것이 바로 map과 reduce입니다.
얼마나 강력하냐면, 맵리듀스라고 이름지어진 프레임워크도 있습니다.
(물론 오늘 다루는 내용은 아닙니다.)

reduce, reduceRight

reduce를 덧셈 함수로 알고 계신 분들이 많은데,
대부분의 사이트에서 reduce 사용 예시를 덧셈으로 들고 있기 때문입니다.
심지어 저도 강좌에서 덧셈으로 예를 들었습니다...
하지만 reduce는 알고보면 매우 강력한 친구입니다.
함께 알아봅시다.

reduce 메서드는 다음과 같이 사용합니다.
배열.reduce((누적값, 현잿값, 인덱스, 요소) => { return 결과 }, 초깃값);

이전값이 아니라 누적값이라는 것에 주의하셔야 합니다.
누적값이기 때문에 다양하게 활용할 수 있습니다.
먼저 흔한 덧셈 예시를 살펴봅시다.

result = oneTwoThree.reduce((acc, cur, i) => {
  console.log(acc, cur, i);
  return acc + cur;
}, 0);
// 0 1 0
// 1 2 1
// 3 3 2
result; // 6

acc(누적값)이 초깃값인 0부터 시작해서
return하는대로 누적되는 것을 볼 수 있습니다.
초깃값을 적어주지 않으면 자동으로 초깃값이 0번째 인덱스의 값이 됩니다.

result = oneTwoThree.reduce((acc, cur, i) => {
  console.log(acc, cur, i);
  return acc + cur;
});
// 1 2 1
// 3 3 2
result; // 6 

초깃값을 적었을 때와 안 적었을 때의 차이점이 보시이죠?

reduceRight는 reduce와 동작은 같지만 요소 순회를
오른쪽에서부터 왼쪽으로 한다는 점이 차이입니다.

result = oneTwoThree.reduceRight((acc, cur, i) => {
  console.log(acc, cur, i);
  return acc + cur;
}, 0);
// 0 3 2
// 3 2 1
// 5 1 0
result; // 6

여기까지는 흔한 덧셈 예제이지만...
reduce는 덧셈 곱셈만을 위한 것이 아닙니다.
초깃값을 활용하여 어떤 일을 할 수 있는지 알아보겠습니다.
map과 filter과 같은 함수형 메서드를 모두 reduce로 모두 구현할 수 있습니다.

위의 map 예제를 reduce로 만들어보겠습니다.

result = oneTwoThree.reduce((acc, cur) => {
  acc.push(cur % 2 ? '홀수' : '짝수');
  return acc;
}, []);
result; // ['홀수', '짝수', '홀수']

초깃값을 배열로 만들고, 배열에 값들을 push하면 map과 같아집니다.
이를 응용하여 조건부로 push를 하면 filter와 같아집니다.
다음은 홀수만 필터링하는 코드입니다.

result = oneTwoThree.reduce((acc, cur) => {
  if (cur % 2) acc.push(cur);
  return acc;
}, []);
result; // [1, 3]

이와 같이 sort, every, some, find, findIndex, includes도
다 reduce로 구현 가능합니다. reduce가 이들 모두의 아버지였던 것입니다. ㅠㅠ

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

초깃값을 Promise.resolve()로 한 후에,
return된 프로미스에 then을 붙여 다음 누적값으로 넘기면 됩니다.
프로미스가 순차적으로 실행됨을 보장할 수 있습니다.

반복되는 모든 것에는 reduce를 쓸 수 있다는 것을 기억하시면 됩니다.

map과 reduce 외에도, 배열의 메서드인
sort, filter, every, some, find, findIndex, includes 정도는 알아두시면 좋습니다.
오늘 reduce만 있어도 다른 메서드들을 다 구현할 수 있다는 것을 배웠기 때문에,
다른 메서드를 까먹으면 reduce로 구현하시면 됩니다!

출처 : reduce 예찬론자

TIL

위 글 덕에 reduce에 대한 이해가 깊어졌다.
이번 첫 HA 레퍼런스에서 이해하기 어려웠던 reduce 초깃값 부분

        <select onChange={handleCategoryChange}>
          <option value = "전체보기">전체보기</option>
          {images.reduce(categoryReducer,[]).map(category =>
            <option value = {category} key = {category}>{category}
            </option>)
          }
        </select>

categoryReducer가 초깃값 빈배열에 담기고 그 내용이 옵션에 매핑 된다는 간단한 얘기
그러니까 왜 나는 초깃값에 할당된 배열을 cur로 생각한 건지. 도른자인가?
이걸로 몇 시간을 쓴거야
ㅋㅋㅋㅋㅋㅋㅋㅋ
아오 멍청아

진정하고.
코어 자바스크립트와 그 기록을 자세히 살펴 보자.
이런 스터디는 기회가 되면 참여 해 보고싶다.

이 글 덕에 오랫동안 묵혀두었던
[HTML + CSS + Javascript 웹프로그래밍]을 다시 꺼내 본다.
붙캠 시작 전에 JS 객체부분만 좀더 딥하게 봤다면
어땠을까.

MJ가 끊임 없이 코어를 말했던 이유를 알겠다.
코어에 대한 이해가 깊을수록 퍼포먼스 스펙트럼은 넓어진다.
이론 공부하며 실무 경험 투덜거릴 때 그녀가 말했지

"이론이 실무고 실무가 이론이다. 공학이라는 게 그런거야."

당시에 재수없던 이 말이 현현하여
좀 더 재수없게 다가온다.
딱 그 만큼 좀 더 공부하자.

하루를 마치며

흘러가는 상황을 보아하니.
과정은 로우 퍼포먼서에게 불친절 해 질 것이고.
나는 답을 찾기 위해 헤매야 할 것이다.

nomade
nomade

다시 밤이 깊었으니
별을 보고 따라가자

profile
Blockchain Web Developer

0개의 댓글