Javascript 고차함수 reduce()에 대해 알아보자

알라딘바지·2023년 11월 22일
1

Frontend interview

목록 보기
2/2
post-thumbnail

저는 고차함수를 좋아합니다.

map, reduce를 애용하는데요.
이것만 있다면 어떤 데이터를 제 앞에 던져줘도 전처리가 가능합니다.

오늘은 reduce()는 어떤 친구인지 알아보겠습니다.


Demo: Array.prototype.reduce

const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;

const sumWithInitial = array1.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  initialValue,
);

console.log(sumWithInitial);
// Expected output: 10

발췌 : MDN


내부적으로 어떤 동작을 하고 있을까?

공식문서를 확인한다면 더할나위 없이 좋습니다.
하지만 모든 책에는 목차가 있듯, 대주제를 훑고 들어간다면 더 빠른 이해가 가능합니다.

Demo코드를 보시면 짐작가능한 동작들이 있습니다.

  1. 3번째 줄 주석이 뭘 말하고 싶은거지? 아, array1의 원소들을 모두 더하는 작업이란걸 설명하고 있구나.
  2. 변수 이름을 accumulator라고 사용했네? accmulator의 뜻이 뭐지? 아, 누산기?
  3. 아, reduce()는 자신을 호출한 배열의 원소들을 돌면서 누산해주는 역할이구나

진짜 대충 reduce()가 어떻게 동작하는지 알았으니 실제로 그런지 확인해봅시다.

arr.reduce(callbackFn, initialValue)

reduce는 크게 보면 2개의 인자를 받습니다.

1. callbackFn: 함수
2. initialValue?: 변수 // 전달하지 않아도 됨

다시, callbackFn(함수)을 작게 보면 4개의 인자를 받습니다.

1. accumulator
2. currentValue
3. currentIndex
4. array

4개의 인자는 각각 어떤 변수인지 간단하게 알아봅시다.

  1. accumulator
    • callbackFn 함수의 return값이 누적될 변수 (반환될 값)
    • initialValue를 전달할 경우 initialValue의 값이 곧 accumulator의 초깃값,
    • initialValue를 전달하지 않을 경우 reduce()를 호출한 배열의 0번째 원소가 곧 accumulator의 초깃값
  2. currentValue
    • reduce()를 호출한 배열의 원소들이 차례로 들어올 변수
    • 다른 예시로, for (const property in object)문의 "property"를 담당
  3. currentIndex
    • 현재 계산하고 있는 배열의 index를 나타낼 변수
    • initialValue를 전달하지 않을 경우 1부터 시작, 전달할 경우 0부터 시작
  4. array
    • reduce()를 호출한 배열

어? 변수들이 하는 역할들을 나열해보니 진짜 내가 생각했던것처럼 동작하는구나?

저는 조금 더 쉽게 설명하고 싶은데요,
위에 적어두었던 Demo: Array.prototype.reduce의 예제코드를 살짝 바꿔 보겠습니다.
코드의 의미는 동일합니다.

더 간단하게 console.log()를 사용하여 알아봅시다.

const array1 = [1, 2, 3, 4];

const initialValue = 0;

function 덧셈을해주는_함수(accmulator, currentValue) {
  return accmulator + currentValue
}

const sumWithInitial = array1.reduce(
  (accumulator, currentValue, index) => {
      console.log("accumulator", accumulator)
      console.log("currentValue", currentValue)
      console.log("index", index)
      
      return 덧셈을해주는_함수(accumulator, currentValue);
  }, initialValue
);

// console //
accumulator 0
currentValue 1
index 0
덧셈을해주는_함수(accumulator, currentValue) 실행

accumulator 1 (0+1)
currentValue 2
index 1
덧셈을해주는_함수(...) 실행

accumulator 3 (1+2)
currentValue 3
index 2
덧셈을해주는_함수(...) 실행

accumulator 6 (3+3)
currentValue 4
index 3
return 덧셈을해주는_함수(6+4) // 10 (순환 종료)

💡 아, accumulator는 그냥 덧셈을해주는_함수()의 반환값을 계속 저장하고 있는 저장소구나


응용 문제

const obj = [{name: "동동", "age": 22}, {name: "아리", "age": "26"}];

const result = obj.reduce((accmulator, currentValue) => {
  const { name, age } = currentValue;
  
  if (age > 23) {
    return [...accmulator, currentValue]
  }
  return accmulator;
}, [])

console.log(result) // ?

result의 값은 무엇일까요??


마치며

저는 reduce 함수를 무척 어려워했습니다.

아무리 공식 문서를 읽어도 그때뿐이고 왜 이렇게 동작하는지도 모른 채 막 사용했었던 때가 있었는데
이번이 저 자신도 한 번 더 공부하는 기회였고,

만약 JS에 처음 입문하시거나 reduce 함수가 익숙하지 않은 분들이 본 글을 읽었을 때 조금이나마
도움을 받았으면 좋겠습니다.

쉽게 설명하는 건 정말 어려운 것임을 다시 한번 깨닫습니다..

더 쉽게 이해할 수 있는 노하우가 있다면 알려주세요!
다음 글에서 담아보겠습니다

다음 글은

Javascript 고차함수 reduce()를 직접 구현해 보자

를 적어보고자 합니다.

profile
Front-end Developer

0개의 댓글