배열 reduce 함수 [JavaScript]

양찌·2021년 5월 11일
7

JS

목록 보기
7/11
post-thumbnail

arr.reduce(callback[, initialValue])
매개변수
1. callback 다음의 네 가지 인수를 받는다
- totalValue: 콜백의 반환값(축적된 총 값)
- currentValue: 현재 배열 내 처리되고 있는 요소
- currentIndex(Optional): 현재 배열 내 처리되고 있는 요소의 인덱스
- array(Optional): reduce 호출에 사용되는 원 배열
2. initialValue(Optional): 콜백의 첫 번째 인수의 값에 사용되는 디폴트 값



제 포스팅 참고 예제의 일부는 아래 사이트를 번역하여 정리하였습니다.



덧셈 등의 사칙 연산

// 예시 1
// arr의 모든 요소의 합을 구해보자!
let arr = [ 13, 63, 29, 57];
let sum = arr.reduce((total, val, idx, arr) => total + val, 0);

console.log(sum);// 162

reduce의 동작 방법은 아래와 같다. reduce는 total의 값과 val값이 서로 더해지면서 쌓이는 것을 볼 수 있다. 위 예시는 intitial value가 0임으로 total의 초기값이 0임을 확인할 수 있다.



최대값과 최소값 구하기

// 예시2
// arr의 최대값과 최소값을 구해보자!
let arr = [ 13, 63, 29, 57];
let isMaxNum = arr.reduce((total, val) => total > val ? total : val);
let isMinNum = arr.reduce((total, val) => total < val ? total : val);

console.log(isMaxNum); // 63
console.log(isMinNum); // 13

최대값을 구하는 동작 과정에서 개별 값은 아래와 같다. 요소들의 앞,뒤를 비교해가면서 total값이 계속 큰 값이 들어가는 것을 볼 수 있다.
아래 예시는 삼항연산자가 아닌 함수를 이용하여 구하였다.



reduce VS map

reduce와 map을 이용해서 배열 요소에 곱하기 2를 해보자


let data = [1, 2, 3];

// 1. reduce 사용예시
let doubled1 = data.reduce(function(acc, value) {
  acc.push(value*2);
  
  return acc;
}, []) // 초기값을 써주는 것을 잊지 말자!

// 2. map 사용예시
let doubledMap = data.map(el => el*2);

console.log(doubled1) // [2, 4, 6]
console.log(doubledMap) // [2, 4, 6]

reduce VS filter

reduce와 filter를 이용해서 홀수 요소를 갖는 배열을 만들어 보자

let data = [1,2,3,4,5,6];

// 1. reduce 사용예시
let odds = data.reduce(function(acc, item){
  if(item % 2) {
    acc.push(item);
  }
  return acc;
},[])

// 2. filter 사용예시
let oddsFilter = data.filter(el => el % 2);

console.log(odds) // [1, 3, 5]
console.log(oddsFilter) // [1, 3, 5]

reduce VS filter & map

만약 어떤 배열에서 짝수를 축출해서, 각 요소마다 2를 곱해줘야 한다면 어떻게 할까?

let data = [1,2,3,4,5,6];

// 1. reduce 사용예시
let reducer = data.reduce(function(acc,item) {
  if(item % 2 === 0) {
    acc.push(item*2);
  }
  
  return acc;
}, []);



// 2. filter과 map 사용예시
let evensFilter = data.filter(el => el % 2 === 0); // 우선 짝수를 축출한다.
let doubled = evensFilter.map(el => el * 2) // 그 후 곱하기 2를 해준다.


console.log(reducer) // [4, 8, 12]
console.log(doubled) // [4, 8, 12]

값은 같지만 reduce와 달리, filter과 map을 사용하여 2번 처리를 해야한다는 것을 알 수 있다.



개별 요소의 빈도를 객채로 표현하기


let vote = ['kim', 'lee', 'song', 'song', 'kim', 'kim','lee', 'han'];

const initialValue = {}; // intialValue는 {} 임으로 결과 값은 객체이다. acc의 초기값은 {}이다

let reducer = function(acc, item) {
  if(acc[item]) { // 축적된 값에 item이라는 속성이 있니? 
    acc[item] = acc[item] +1; // 있으면 acc.item에 +1을 해라
  } else { // 없으면
    acc[item] = 1; // acc.item = 1 이다
  }
  
  return acc; // 축적된 총 값을 리턴해라
};

const result = vote.reduce(reducer, initialValue);

console.log(result); // {kim: 3, lee: 2, song: 2, han: 1}



reduce함수 안에서 다른 함수 호출하기

한 함수의 계산 값을 입력받아 다른 함수에 넣고, 그 값을 입력받아 또 다른 함수에 넣으려면 어떻게 해야 할까?

function increment(input) {return input + 1;}
function decrement(input) {return input -1;}
function double(input) {return input * 2;}
function halve(input){return input / 2;}

let initial_value = 1;

우선 아래와 같이 하나하나 값을 전달하는 방법이 있을 것이다.

let incremented_value = increment(initial_value);
let doubled_value = double(incremented_value);
let final_value = decrement(doubled_value);

console.log(final_value); // 3




위의 과정을 보기 가독성있고, 간결하게 정리하는 방법은 없을까?
reduce를 활용하여 위에 코드를 정리해보자.

// 여러가지 함수를 배열에 담는다.
let pipeline = [
  increment,
  increment,
  increment,
  decrement,
  double,
  double,
  halve
];

// 배열의 요소를 함수 이름으로 하고
// reduce 함수 안에서 그 함수를 호출한다.
// 축적된 값은 함수의 전달인자로 전달한다.
let final_value = pipeline.reduce(function(acc, fn){
  return fn(acc);
}, initial_value);

console.log(final_value); // 6

위와 같이 reduce의 전달인자로 함수를 받고, 축적된 값을 전달받은 함수의 인자로 반복적으로 받는 로직을 만들어 위에 복잡한 코드를 정리할 수 있겠다.👍

profile
신입 개발자 입니다! 혹시 제 글에서 수정이 필요하거나, 개선될 부분이 있으면 자유롭게 댓글 달아주세요😊

0개의 댓글