[JavaScript] reduce

김진용·2023년 4월 3일

자바스크립트

목록 보기
5/6
post-thumbnail

🙄 공부하게 된 이유

Arrayreduce() 메서드는 배열 요소의 전체 합을 구할 때에 주로 사용했다.

프로그래머스의 추억 점수라는 문제를 풀면서 reduce() 메서드를 평소처럼 누적합을 구하는데 사용했는데, 더 복잡한 환경에서 활용할 수 있는 방법이 있는지 궁금해서 공부하게 되었다

다른 분들은 이미 알고 있는 부분일수도 있습니다!!
잘못된 부분이나 추가되어야 하는 부분이 보인다면 댓글로 알려주시면 감사하겠습니다.

🤔 reduce()는 무엇일까?

MDN 문서에서 설명하는 reduce() 메서드는 다음과 같다.

배열의 각 요소에 대해 리듀서 함수를 실행하고, 하나의 결과값을 반환한다

결국 reduce() 메서드의 목적은 하나의 결과값을 얻기 위해서라는게 된다.

그래서 배열 요소의 합을 구하는 예제에 주로 사용되었던 것!

😎 reduce()의 구조

arr.reduce(callback[, initValue]) 로 표현된다.

이 의미는 첫 번째 인자로 callback 함수를 받으며, 두 번째 인자는 선택적으로 initValue 를 받을 수 있다는 의미가 된다.

reduce() 의 첫 번째 콜백 함수는 앞서 말한 리듀서 함수가 된다.

이 리듀서 함수는 4개의 인자를 가지는데 각각은 아래와 같다.

  1. 누산기
    이 값에 리듀서 함수의 반환값이 누적되게 된다.
    리듀서 함수의 반환값으로 매번 갱신되고, 마지막 값이 최종 결과로 reduce() 메서드의 반환값이 된다.
  2. 현재값
    배열을 순회하고 있는 배열 요소의 값
  3. 현재 인덱스
    배열을 순회하고 있는 배열 요소의 인덱스
    이 인자는 선택 사항이다
  4. 원본 배열
    원본 배열
    이 인자는 선택 사항이다.

콜백 함수라는 부분에서 화살표 함수로도 사용할 수 있고, 복잡한 동작은 분리해서 사용할 수도 있다는 것을 예상할 수 있다.

그리고 initValue 는 누산기에 저장될 최초의 값이 된다.

⭐ 중요한 부분을 알게 되었는데, initValue 의 존재 여부에 따라 맨 처음 누산기현재값이 달라진다는 것이었다! ⭐

  1. initValue 가 없는 경우
    최초 호출 시 누산기는 배열의 첫 번째 값이 되고, 현재값은 배열의 두 번째 값이 된다.
  2. initValue 가 있는 경우
    최초 호출 시 누산기는 initValue 가 되고, 현재값은 배열의 첫 번째 값이 된다.

이 특성이 어떻게 영향을 끼치는지 확인하려고 아래의 예시를 만들어봤다.

// 3일 동안의 지출 내역
const payments = [[10, 5, 20], [7], []];

// 초기값이 있는 경우 => 오류 없음
payments.forEach(payment => {
  console.log(payment.reduce((acc, cur) => acc + cur, 0));
});

// 초기값이 없는 경우 => 빈 배열에서 오류 발생
payments.forEach(payment => {
  console.log(payment.reduce((acc, cur) => acc + cur));
});

초기값이 없는 경우, 빈 배열을 만났을 때 오류가 발생했고 메시지로 초기값을 부여하라고 했다!

👉 초기값 넣어주는 것을 생활화하자 (손해볼게 없으니까....)

😎 활용 예시

나는 코드를 짜면서 3번, 4번 인자는 사용해본 기억이 없었다...
대부분 총합을 구할 때만 한정적으로 reduce() 를 사용했기 때문이었다.

그래서 4번 인자는 특히 쓸 일이 있는지 궁금했고, 여러 예시를 생각하다보니 활용도가 있는 부분이었다는 것을 알 수 있었다.

리듀서 함수(콜백 함수)가 가질 수 있는 4개의 인자를 활용하는 예시를 한 번씩 보자

const names = ["Kim", "Lee", "Park", "Choi"]
const score = [70, 80, 90, 100];

// 1. score의 총합 구하기
const result1 = score.reduce((acc, cur) => acc + cur, 0)

// 2. score의 평균 구하기
const result2 = score.reduce((acc, cur, idx, array) => {
  if (idx === array.length - 1) {
    acc += cur;
    return acc / array.length;
  };

  return acc + cur
}, 0);

// 3. names와 score의 각 요소를 키-값 으로 가지는 오브젝트 객체 만들기
const result3 = score.reduce((acc, cur, idx) => {
  acc[names[idx]] = cur;
  return acc; 
}, {})

😶 결론

reduce() 이용하면 배열을 이용해 하나의 결과값을 내는데 활용할 수 있다는 것을 알게 되었다.

개발자가 되고 싶다면서 언어에서 제공하는 메서드를 제대로 활용하지 못하고 있었다는 반성을 할 수 있었다.

지금까지 풀었던 알고리즘 문제에서 reduce() 메서드를 활용했을 때 더 깔끔하게 코드를 작성할 수 있는 문제가 있었을 것 같다.

앞으로는 배열의 요소를 이용해 하나의 결과값을 내야 할 때가 온다면 reduce() 메서드를 사용하는 연습을 하면서 익숙해질 수 있게 노력해보려고 한다!

profile
개발자가 되기 위해 꿈틀대고 있습니다.

0개의 댓글