본문 바로가기

javascript/Methods

TIL no.54 - array.reduce() : javascript array method

 

지금까지 map, forEach 를 반복문을 사용할 때 유용하게 사용했습니다.

reduce는 위 array 메서드가 할 수 있는 부분을 다룰 수 있으며 더 복잡한 구조도 다룰 수 있는 아주 유용한 메서드입니다.

또한 배열로만 반환하는 것이 아니라 원하는 데이터 구조로 반환하는 것이 가능합니다. 👍🏻

그렇다고 map과 forEach 대신 무조건적으로 사용해서는 안됩니다.

코드의 가독성을 위해 map과 forEach로도 가능한 간결한 코드에서는 적절한 메서드를 사용하는 것이 좋습니다.

 

array.reduce()

arr.reduce(callback[, initialValue])

reduce는 첫번째 인자로 콜백함수를 받습니다.

그래서 반복문을 반복하는 숫자만큼 콜백함수가 실행됩니다.

initialValue 로는 초기값으로 설정해주고 싶은 값을 넣어주면 됩니다.

 

콜백함수에는 다음의 네 가지 인수를 받습니다.

 

- accumulator

accmulator는 콜백의 반환값을 누적합니다. 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값입니다.

 

- currentValue

처리할 현재 요소.

 

- currentIndex

처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작합니다.

 

- array

reduce()를 호출한 배열.

 

 

 

reduce의 사용법 설명을 위해 map과 filter 와 비교하며 정리하겠습니다.

 

const arr = [9,2,8,5,7];

let result2 = 0;
let resultArr = [];

arr.forEach(num => resultArr.push(result2 += num))

//결과 resultArr : [ 9, 11, 19, 24, 31 ]

filter는 map과는 다르게 undefined를 반환합니다.

그래서 원하는 값을 반환해주기 위해 위와 같이 변수에 값을 담아주고 그 변수를 반환하여 원하는 배열을 가져왔습니다.

 

 

const arr = [9,2,8,5,7];
let result = 0;

const mapResult = arr.map(num => result += num)

// mapResult 결과 : [ 9, 11, 19, 24, 31 ]

map은 반복문으로 원하는 함수를 실행하여 값들을 배열로 반환합니다.

 

 

위 함수를 reduce 로 실행하게 된다면

const arr = [9,2,8,5,7];
const reduceResult =  arr.reduce((acc, cur) => {
  return acc + cur
}, 0)

// reduceResult 결과 : 31

reduce는 함수를 실행하는 동안 반복적으로 값들을 쌓아서 하나의 값을 반환합니다.

물론 배열로 반환하고 싶다면 그렇게 하는 것도 가능합니다.

 

const arr = [9,2,8,5,7];

let result2 = 0;
let resultArr = [];

const reduceResult =  arr.reduce((acc, cur) => {
    result2 = result2 + cur; 
    acc.push(result2);
  
    return acc;
}, [])

// reduceResult 결과 : [ 9, 11, 19, 24, 31 ]

이렇게 작성하면 map, forEach와 같은 값을 반환할 수도 있습니다.

 

***reduce 는 map, filter와는 다르게 좀 더 복잡하고 세세한 구조를 다룰 수 있고 좀 더 유연한 메서드라는 생각이 들었습니다.

 

 

 

저는 이번에 제품의 총수량과 총가격을 구하는 함수를 만들 때 reduce를 사용했습니다.

  const sumQuantity = (cart: ICartItems[]) => {
    return cart.reduce((acc, cur) => {
      if (!cur.isChecked) return acc;
      return acc + cur.cartItemCount;
    }, 0);
  };


  const sumPrice = (cart: ICartItems[]) => {
    return cart.reduce((acc, cur) => {
      if (!cur.isChecked) return acc;
      return acc + cur.cartItemCount * cur.product_price;
    }, 0);
  };

 

 

이 부분을 이렇게도 작성가능합니다.

  const sumQuantity = (cart: ICartItems[]) => {
    return cart.reduce((acc, {isChecked, cartItemCount}) => {
      if (!isChecked) return acc;
      return acc + cartItemCount;
    }, 0);
  };

  const sumPrice = (cart: ICartItems[]) => {
    return cart.reduce((acc, {isChecked, cartItemCount, product_price}) => {
      if (!isChecked) return acc;
      return acc + cartItemCount * product_price;
    }, 0);
  };