[JS]Reduce 함수

 

코테 준비를 하면서 다른 분들의 코드를 보면 reduce 함수를 사용한 경우를 많이 볼 수 있다.

많은 사람들이 사용하고 유용한 reduce 함수에 대해서 알아보자!

 

⭐️ reduce 함수란?

배열이나 객체 요소를 순차적으로 순회하며 함수를 실행하고 하나의 결과 값으로 반환해준다.

 

⭐️ 사용법

arr.reduce(callback, [, initialValue])

reduce 함수는 빈 요소를 제외하고 배열 내에 존재하는 각 요소에 대해 callback 함수를 한 번 씩 실행하는데,
콜백 함수는 다음의 네 인수를 받습니다(1~4).
  1. accumulator(누산기) : 반환 값을 누적하는 곳. initialValue를 제공하는 경우, initialValue이 할당된다.
  2. currentValue(현재 값) : 처리할 현재 요소 
  3. currentIndex(현재 인덱스) : 처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작한다.
  4. array(원본 배열) : reduce()를 호출한 배열
  5. initialValue : callback의 최초 호출에서 첫 번째 인수에 제공하는 값이다. 
    이 값을 제공하지 않으면 배열의 첫 번째 요소를 초기값으로 사용한다.

1~4번은 reduce 함수의 callback의 인수이고, 5번은 reduce 함수의 인수이다.

3, 4, 5번은 옵션이다.

 

initialValue 제공하지 않은 경우, accumulator의 초기 값은 원본 배열의 첫번 째 값이 되고, currentIndex는 1부터 시작된다.

initialValue를 제공한 경우, accumulator의 초기 값은 initalValue의 값이 되고, currentIndex는 0부터 시작된다.

 

설명만 봤을 때는 조금 어렵게 느껴지니 예제도 같이 살펴보자...!

 

예제 1 - 배열의 합

let sum = [1, 2, 3, 4, 5].reduce((acc, cur) => acc + cur);
console.log(sum);	// 15

initialValue를 제공하지 않은 경우이다.

let sum2 = [1, 2, 3, 4, 5].reduce((acc, cur) => acc + cur, 10);
console.log(sum2);	// 25

initialValue를 제공한 경우이다.

 

예제 2 - 객체 배열의 합

let sum = [{ x: 1 }, { x: 3 }, { x: 5 }].reduce((acc, cur) => acc + cur.x);
console.log(sum);	//[object Object]35

객체 배열의 합을 구할 때, initalValue를 지정해주지 않으면 위의 코드를 실행시켰을때 아래와 같이 출력된다.

'acc'는 {x : 1}이 되고, 'cur.x'에는 3이 할당되서 '{x : 1} + 3'으로 해석된다.

객체와 숫자의 덧셈은 문자열로 간주되기 때문에

'{x : 1}'이 '[object Object]'로 변환되고 그 뒤에 3이 더해져서 '[object Object]3'이 반환된다.

그 다음, '[object Object]3' + 5로 계산되기 때문에 최종적으로 반환되는 값은  '[object Object]35'가 되는 것이다.

 

이런 문제를 해결하기 위해서는 initialValue의 값을 제공해주면 된다.

위의 코드에서 초기 값만 0으로 제공해준다면 원하는 값을 반환받을 수 있다.

let sum = [{ x: 1 }, { x: 3 }, { x: 5 }].reduce((acc, cur) => acc + cur.x, 0);
console.log(sum);	// 9

 

예제 3 - 배열의 최댓값 찾기

let numbers = [3, 1, 5, 9, 7];
let max = numbers.reduce((acc, cur) => {
  return acc < cur ? cur : acc;
});
console.log(max);	// 9

삼항연산자를 사용하여 acc와 cur의 값을 비교하고, 더 큰 값을 max에 넣어준다.

예제 4 - 배열 안의 알파벳 갯수 세기

let alphabets = ["a", "a", "b", "b", "b"];
let number = alphabets.reduce((acc, cur) => {
  console.log(acc[cur]);
  if (acc[cur]) acc[cur] += 1;
  else acc[cur] = 1;
  return acc;
}, {});
console.log(number);	// { a: 2, b: 3 }

초기 값으로 빈 객체를 선언해준다.

acc[cur]이라는게 무엇을 의미하는지 몰라서 콘솔로 찍어봤다.

undefined, 1, undefined, 1, 2 가 나왔다.

1. 초기 값인 빈 객체가 acc에 들어갔고 빈 객체에는 아무런 값도 들어있지 않기 때문에 acc["a"]이 값이 undefined가 출력된 것이다.

이후 else 문에 걸려서 acc["a"]=1이 된다.

2. acc["a"]=1이기 때문에 1이 출력되었다. if 문에 걸려서 acc["a"]=2가 된다.

3. acc["b"]라는 값이 acc안에 존재하지 않기 때문에 또 다시 undefined가 출력된 것이다. else문에 걸려서 acc["b"]=1이 된다.

4. acc["b"]=1이기 때문에 1이 출력되었다. if 문에 걸려서 acc["b"]=2가 된다.

5. acc["b"]=2이기 때문에 2가 출력되었다. if 문에 걸려서 acc["b"]=3이 된다.

 

최종적으로는 acc 객체에 저장된 { a : 2, b : 3 }이 출력되는 것이다.

 

느낀점

어려워보였지만 막상 까보니 그닥 어렵게 느껴지진 않았다. 

이제까지 미뤄왔던게 살짝 후회될 정도..

코테 풀때나 코드 짤 때 사용해봐야겠다!!

 

'JavaScript' 카테고리의 다른 글

JS This  (0) 2024.08.07
JS 동작원리  (0) 2024.08.05
[JS] 유효성 검사  (0) 2023.12.30
[JS]JavaScript 화살표 함수  (0) 2023.05.29
JavaScript Closure(+실행 컨텍스트와 스코프 체인을 곁들인..)  (0) 2023.05.29