내일배움캠프 TIL(230131): js reduce 함수 예제 정리 (1)

Jiumn·2023년 1월 31일
0

Javascript reduce 함수 정리

배열 안의 요소를 순회하면서 하나의 값으로 만들어주는 reduce 함수. map, filter와 함께 많이 쓰이는 메서드라서 연습하는데 헷갈리고 어렵다. 。° ૮₍°´ᯅ`°₎ა °。

나중에 헷갈릴 때 다시 보려고 예제 몇 가지를 수도코드와 함께 정리해본다.

배열에서 나이별 사람 수 구하기

  • 결과 값: {26: 2, 75: 1, 50: 1}
const users = [
  { firstName: "akshay", lastName: "saini", age: 26 },
  { firstName: "donald", lastName: "trump", age: 75 },
  { firstName: "elon", lastName: "musk", age: 50 },
  { firstName: "deepika", lastName: "padukone", age: 26 },
];

reduce를 이용해 배열 안의 객체를 순회하면서 같은 나이가 있으면 1씩 추가를 해주는 방법으로 코드를 짠다.

✅ 우선 reduce 함수의 형식을 기본 세팅한다.

const result = users.reduce((prev, cur) => {}, {})

prev는 현재값 이전까지의 누적값이고 cur는 순회하는 현재 값이다.
그 외에 인자로 index(현재의 인덱스), array(원본 배열)을 추가할 수 있다.
(이 예제에서는 인덱스와 배열을 불러올 필요가 없으니 누적값과 현재 값만 다룬다.)

화살표 옆에 2개의 중괄호가 보이는데, 두 번째 중괄호는 초깃값이다.
초깃값을 빈 객체({})로 지정해서 빈 객체 안에 값을 추가해줄 것이다.

reduce의 두 인자(prev, cur)가 순회할 때마다 값을 어떻게 할당하는지 궁금하다면
console.log()를 찍어보면 된다.

const age_sum = users.reduce((prev, cur) => {
  console.log(prev, cur);
}, {});

// console.log 결과
{} { firstName: 'akshay', lastName: 'saini', age: 26 }
undefined { firstName: 'donald', lastName: 'trump', age: 75 }
undefined { firstName: 'elon', lastName: 'musk', age: 50 }
undefined { firstName: 'deepika', lastName: 'padukone', age: 26 }
undefined

두 번째 인덱스부터 prev가 undefined인 이유는 아직 return 값을 지정하지 않았기 때문이다.

const age_sum = users.reduce((prev, cur) => {
  console.log(prev, cur);
  return prev
}, {});

// console.log 결과
{} { firstName: 'akshay', lastName: 'saini', age: 26 }
{} { firstName: 'donald', lastName: 'trump', age: 75 }
{} { firstName: 'elon', lastName: 'musk', age: 50 }
{} { firstName: 'deepika', lastName: 'padukone', age: 26 }
{}

return 값으로 prev를 지정하면 빈 배열이 나온다.
아직 누적값을 어떻게 처리해줄지 console.log()와 return 사이에 정하지 않았기 때문이다.

✅ 이제 두 인자를 받아서 어떻게 처리할 지 첫 번째 중괄호 안에 작성한다.

그럼 최종적으로 우리가 반환할 값은 prev이므로,
prev 안에는 {나이1: 나이1를 가진 사람의 수, 나이2: 나이2를 가진 사람의 수...}와 같은 형태로 데이터가 누적되어야 한다.

먼저 초깃값(빈 배열)부터 시작한다. 가장 처음의 초깃값은 prev와 같다.
여기에 각 객체의 나이를 담아야 한다.
현재 객체의 나이는 cur.age로 구할 수 있다.
이걸 식으로 표현하면 prev[cur.age]가 된다.

여기서부터 진도를 어떻게 나가야 할지 발상이 어려울 수 있는데,
reduce 함수에서는 초깃값(누적값, 즉 이전값)과 현재값을 비교할 수 있음을 떠올린다.

✅ 따라서 이전값에 현재 객체의 나이가 있으면 객체를 하나 더 추가해주고, 이전값에 현재 객체의 나이가 없으면 그 값은 1을 할당한다.

이 논리를 식으로 표현하면 이렇다.

const age_sum = users.reduce((prev, cur) => {
  console.log(prev, cur);
    if (prev[cur.age]) {
      prev[cur.age] += prev[cur.age];
    } else {
      prev[cur.age] = 1;
    }
  return prev;
}, {});

객체의 실제 데이터에 대입해서 설명해본다면
첫 번째 라운드에서 age는 26이다. 이전까지 누적된 값에 26이 있는지 확인한다.
초깃값이 빈 배열이므로 없다. 값에 1을 할당한다.

{ 26: 1 } 

두 번째 라운드에서 agr가 75다. 이전까지 누적된 값에 75가 있는지 확인한다.
age는 26인 객체만 있으므로 값에 1을 할당한다.

{ 26: 1, 75: 1 } 

이런 식으로 추가해나간다. 마지막 age는 26이므로 26의 값에 하나 더 증가한다.

{26: 2, 75: 1, 50: 1}

최종 결과 값이 잘 반환된다.

profile
Back-End Wep Developer. 꾸준함이 능력이다. Node.js, React.js를 주로 다룹니다.

0개의 댓글