[javascript] 6. 배열 내장 함수 - reduce

HongDuHyeon·2022년 2월 8일
2
post-thumbnail
post-custom-banner
여긴 어디.. 나는 누구...

앞에 챕터에서 했던 배열 내장 함수는 아무것도 아니었다.
reduce 이건 진짜 ㅋㅋㅋㅋㅋㅋㅋㅋ

reduce

reduce는 주로 배열이 주어졌을때 배열안에 있는 모든 값들을 사용하여 연산할 때 사용함

배열의 모든 총합을 구해보자

forEach

  • 예제 1
const numbers = [1, 2, 3, 4, 5];
let sum = 0;
numbers.forEach((n) => {
  sum += n;
});
console.log(sum);
// 15

forEach로도 충분히 가능하다 하지만 reduce를 사용해보면 좀 더 간결하게 작성 가능하다.

reduce

  • 예제 1
const numbers = [1, 2, 3, 4, 5];

//                                A         B                   C
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum);

일단 배열의 모든 총합을 구해보는 함수를 하나 만들어줄것이다.
두가지 파라미터를 가져올건데
먼저 accumulator는 누적된 값을 뜻하고, current는 각 원소를 뜻한다고 보면 된다.
맨 뒤에 0이 뜻하는건 초기 accumulator값을 설정했다고 생각하면 된다.


주석 처리 된 A B C를 자세히 살펴보자
먼저 A(accumulator)에 배열의 원소 1이 들어가게 된다. 그럼 옆에 있는 B(current)에는 맨 뒤에 설정 해주었던 초기값 0을 가져오게 된다. 그 결과값으로는 어떻게 연산할지 작성을 해줘야하는데 그걸 C(accumulator + current)로 표시했다. C의 이유는 모든 총합을 구해야하니까요...

자 그럼 reduce가 어떻게 작동하는지 방식을 살펴보자. 꽤 헷갈릴수도 있다.

  1. 맨뒤에 설정해두었던 초기값 0이 A로 들어오게 된다.
  2. sum이라는 배열에 있는 0번째 1이 B로 들어오게 된다.
  3. 그 두개를 파라미터로 전달하게 되면 값은 1이 나오고 여기서 나온 1이라는 값이 다시 A로 이동하고 B에는 두번째 배열 원소인 2가 들어오게 된다.
  4. 이런식으로 진행하다보면
 0 + 1 = 1
 1 + 2 = 3
 3 + 3 = 6
 6 + 4 = 10
 10 + 5 = 15
    

진행 방식은 이렇게 된다고 보면 된다.

평균값 구하기

  • 예제 1
const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, current, index, array) => {
  if (index === array.length - 1) {
    return (accumulator + current) / array.length;
  }
  return accumulator + current;
}, 0);
console.log(sum);
// 15

파라미터 친구들이 더 생겼다. 왜?
기존에 있던 accumulator와 current는 똑같은 기능을 하고 새로 생긴 indexarray를 한번 살펴보자.

index는 각 원소가 몇번째 아이템인지 알려준다. 위에 numbers를 기준으로 하면 0부터 4까지로 보면 된다.
array는 reduce를 실행하고 있는 현재 배열을 뜻하고 있다. 위에선 numbers를 의미한다.

  1. if문 안에 index가 4까지 처리할 수 있도록 구문을 작성해준다. (index는 0부터 시작이니까 -1을 붙혀주자)
  2. 먼저 if문 안을 살펴보면 평균값을 구해야하니 예제 1에서 했던 연산에 나누기로 배열의 총 길이를 뜻하는 array.length를 적는다.
  3. 그리고 if문에 적었던 조건과 부합하지 않을경우 accumulator를 계속 더해줘야하니 밑에 return 값으로
    accumulator + current 를 적어둬서 조건문에 부합할때까지 계속 누적이 될수 있도록 만들어 놓는다.
  4. 종합해보면 if문이 걸릴때까지 계속 연산을 실행해서 누적 시키고 if문에 걸리면 계속 누적된 값을 평균으로 나누게 된다.

알파벳들이 각 배열안에 몇개씩 있는지 세어서 객체에 결과를 넣어보자

const alphabets = ["a", "a", "a", "b", "c", "c", "d", "e"];

const counts = alphabets.reduce((acc, current) => {
  if (acc[current]) {
    acc[current] += 1;
  } else {
    acc[current] = 1;
  }
  return acc;
}, {});

console.log(counts);
// {a: 3, b: 1, c: 2, d: 1, e: 1}
  1. alphabets 배열 안에 중복된 원소가 몇개 있는지 확인하고 객체(acc)를 생성한다. (코드블록 맨뒤 , {})
  2. 먼저 if문에서 acc 안에 current가 존재하는지 확인하는 로직을 적는다.
  3. current의 초기값은 "a"이다. 그렇게 되면 acc["a"]가 되고 acc.a와 같아진다.
  4. true값이면 acc안에 있는 current가 존재한다면 값에 1을 더해준다. +=
  5. 그렇지 않다면 else문에 값을 1로 설정한다. =
  6. 그리고 마지막에 return acc를 선언해준다.

4번, 5번을 하는 이유는 reduce를 실행하고 같은 값이 있는 원소들은 숫자를 증가시키고 한개밖에 없는 숫자들은 1로 표현하기 위함이다.

비어있는 객체에 "a"가 있는지 먼저 확인하고 비어있으니 else문이 실행되고 객체 안에 "a"값을 1이라고 먼저 만들어진다. 그리고 reduce가 두번째 인자에 접근해서 if문을 돌리게 되면 "a"값이 이미 만들어져서 존재하고 있으니 true에 속해져서 1이 한번 더 올라간다. 한개밖에 없는 "b","d","e"는 else문에 걸리게 되고 값이 하나밖에 없으니 1이 되고 다음 원소를 계속 진행하게 된다.

이렇게 reduce가 끝나게 되고 마지막으로 return acc를 실행하게 되면 다음과 같이 값이 나온다.

{a: 3, b: 1, c: 2, d: 1, e: 1}
profile
마음이 시키는 프론트엔드.. RN과 IOS를 곁들인..
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 5월 7일

이해 확실히 하고갑니다!

답글 달기