본문 바로가기

2주차

자바스크립트 reduce 메서드 알아보기

안녕하세요 ! 웹 YB 김가현입니다.

2주차 공유과제로는 reduce 메서드에 대해 작성해보려고 합니다.

문법이 복잡할 것 같고 …. 코드를 봐도 잘 와닿지 않아서 자주 손이 가는(?) 메서드는 아니었는데요 ,,

저와 같이 하나 하나 뜯어봅시다 !!!!

 


 

Array.prototype.reduce()

 

reduce는 '줄이다' 라는 의미를 가지고 있다.

이 의미에서 알 수 있듯 배열의 각 요소를 순차적으로 처리하며 하나로 줄이는(reduce) 작업을 수행한다.

 

기본 문법

arr.reduce(callback[, initialValue])

 

가장 기본적인 형태이다. 

callback -> 콜백함수에는 다음 4가지의 인수를 받을 수 있다.

  • 누적 값 (accumulator)
  • 현재 값 (currentValue)
  • (optional) 현재 인덱스 (currentIndex)
  • (optional) 원본 배열 (array)

initialValue (optional)
callback 함수의 초기값으로, 따로 초기값을 제공하지 않으면 배열의 첫번째 요소를 사용한다. 

 

이 때, 콜백 함수에서 리턴되는 값은 다음 element에 대한 callback 함수 실행 시 파라미터인 accumulator로 입력되어 활용된다.

배열의 모든 element들에 대해 콜백 함수 실행이 완료되면, reduce() 함수는 마지막 element의 콜백 함수의 리턴값을 리턴한다.

따라서, reduce() 함수를 사용하면 배열을 순차적으로 순회하면서 배열의 값을 누적하는 데 유용하게 사용될 수 있다 😮

 

여기서 주의할 점은 initialValue를 설정하는 경우, cur는 index 1이 아닌 index 0부터 시작하여 순회한다는 것이다 !!

예를 들어, initialValue를 설정하지 않는다면 acc는 배열의 첫 번째 요소가 되고 cur는 두 번째 요소(index 1)부터 시작하지만,

initialValue를 설정하면 acc에 해당 값이 들어가고, cur는 배열의 첫 번째 요소(index 0)부터 시작하게 된다.

같은 배열이지만 index 0의 주인이 달라지는 셈이니 가능하다면 initialValue를 설정하는 것이 좋다 ~! 

const array = [1, 2, 3];

// initialValue를 지정하지 않은 경우
array.reduce((acc, cur) => {
    console.log(acc, cur); // acc는 1, cur는 2부터 시작
    return acc + cur;
});
// 출력: 1 2, 3 3

// initialValue를 지정한 경우
array.reduce((acc, cur) => {
    console.log(acc, cur); // acc는 0, cur는 1부터 시작
    return acc + cur;
}, 0);
// 출력: 0 1, 1 2, 3 3

 

활용 예제

배열의 합계 구하기

const arr = [1, 2, 3, 4, 5]
  
arr.reduce(function (acc, cur, idx) {
  console.log(acc, cur, idx);
  return acc + cur;
}, 0);

// 15

가장 흔히 사용되는 예시라 할 수 있다. 

return값으로 이전값(누적값)과 현재값의 덧셈을 받아오고 있고 그에 따라서 순회하는 배열 요소들의 합을 구하는 것이다.

 

 

 

평균 계산하기

const numbers = [10, 20, 30, 40, 50];

const average = numbers.reduce((acc, current, index, array) => {
  acc += current;
  if (index === array.length - 1) {
    return acc / array.length;
  } else {
    return acc;
  }
}, 0);

console.log(average); // 30

 

reduce에는 누적값을 반환하는 변수가 내장되어 있다는 것을 활용하면, 평균을 쉽게 구할 수 있다.

 

 

Object 배열 활용하기 - Grouping

  let people = [
    { name: 'Kim nugu', city: 'Seoul' },
    { name: 'Lee nugu', city: 'Busan' },
    { name: 'Park nugu', city: 'Seoul' },
    { name: 'Choi nugu', city: 'Suwon' },
  ];
  
  function groupBy(objectArray, property) {
    return objectArray.reduce(function (acc, obj) {
      let key = obj[property];
      if (!acc[key]) {
        acc[key] = [];
      }
      acc[key].push(obj);
      return acc;
    }, {});
  }
  
  let groupedPeople = groupBy(people, 'city');
  console.log(groupedPeople);

city 속성에 따라 people 배열을 그룹화하여 각 도시 이름을 key로 하고 name을 배열로 나열한 객체를 반환한다.

 

첫 번째 요소를 순회할 때는 key가 Seoul이 된다. acc 객체에 'Seoul' 키가 없기 때문에 빈 배열을 추가하고 Kim nugu를 Seoul 배열에 추가한다. 해당 과정을 반복하다 보면

{
  "Seoul": [
    { name: 'Kim nugu', city: 'Seoul' },
    { name: 'Park nugu', city: 'Seoul' }
  ],
  "Busan": [
    { name: 'Lee nugu', city: 'Busan' }
  ],
  "Suwon": [
    { name: 'Choi nugu', city: 'Suwon' }
  ]
}

위와 같은 구조의 객체가 출력된다.

 

 

Object 배열 활용하기 - Counting

let fruits = ['Apple', 'Banana', 'Apple', 'Orange', 'Banana', 'Apple'];

let countedFruits = fruits.reduce(function (allFruits, fruit) { 
  if (fruit in allFruits) {
    allFruits[fruit]++;
  } else {
    allFruits[fruit] = 1;
  }
  return allFruits;
}, {});

console.log(countedFruits);

reduce 함수가 실행되면 allFruits 객체는 {}로 초기화된다. 이 객체에는 각 과일의 갯수를 누적하여 저장한다.

간단히 로직을 살펴보면  첫 번째 요소인 'Apple'이 allFruits에 없으므로 새로운 키를 추가하고 값을 1로 설정하고, allFruits는 { Apple: 1 }이 된다. 두 번째 요소인 'Banana' 역시 allFruits에 없으므로 새로운 키를 추가하고 값을 1로 설정한다. allFruits는 { Apple: 1, Banana: 1 }이 된다. 이 과정을 반복하다 보면

 

 

 

{
  Apple: 3,
  Banana: 2,
  Orange: 1
}

위와 같은 object를 얻을 수 있게 된다 !

 

 

 


이렇게 reduce 메서드의 다양한 활용 방법을 살펴보았는데요 !

다소 복잡해 보일 수 있지만 활용 범위가 굉장히 넓은 메서드이니 알아두면 좋을 것 같다는 생각이 듭니다 ~~~

저는 이번 과제를 하면서, 새 멤버를 추가할 때 id를 부여하는 부분에 reduce로 id의 최댓값을 찾고 +1 한 값을 id로 설정하도록 했는데

앞으로도 다양한 방법으로 활용해 볼 생각입니다 ! (코테 풀 때도 좋겠죠 ??!?!?)