ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [javascript] 자바스크립트 map & reduce 메소드란?
    JavaScript 2022. 6. 10. 13:22
    반응형

    자바스크립트 내장 메서드 중에서 제일 강력하고, 알아두면 다양한 곳에 활용할 수 있는 것이 바로 map과 reduce이다.

    1. map

    map 메서드는 다음과 같이 사용한다. 배열.map( (요소, 인덱스, 배열) => { return 요소 } );

    map의 기본 원리는 간단하다. 반복문을 돌며 배열 안의 요소들을 1대1로 짝지어 준다.  매핑한다고 표현하며 어떻게 짝지어줄 것인가 정의한 함수를 메서드의 인자로 넣어주면 된다. 일단 주어진 배열을 그대로 매핑해보자.

    const oneTwoThree = [1, 2, 3];
    let result = oneTwoThree.map((v) => {
      console.log(v);
      return v;
    });
    // 콘솔에는 1, 2, 3이 찍힘
    oneTwoThree; // [1, 2, 3]
    result; // [1, 2, 3]
    oneTwoThree === result; // false

    반복문으로 요소를 순회(1, 2, 3 순서로)하면서 각 요소를 어떻게 짝지어줄지 알려준다. 함수가 그냥 return v를 하기 때문에 같은 값을 그대로 짝짓는다. 알아둘 점은, map을 실행하는 배열과 결과로 나오는 배열이 다른 객체라는 것입니다. 기존 배열을 수정하지 않고 새로운 배열을 만들어낸다. 단, 배열 안에 객체가 들어있는 경우, 객체는 공유된다.

    이번에는 각 요소에 1씩 더한 값을 반환해보자

    result = oneTwoThree.map((v) => {
      return v + 1;
    });
    result; // [2, 3, 4]

     

    규칙적인 배열만 반환할 수 있는게 아니라, 함수 안에 적어준대로 반환할 수 있기 때문에 자유도가 높습니다.

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.map((v) => {
      if (v % 2) {
        return '홀수';
      }
      return '짝수';
    });
    result; // ['홀수', '짝수', '홀수']

    정리하자면, map은 배열을 1대1로 짝짓되 기존 객체를 수정하지 않는 메서드 이다.

     

    2. reduce, reduceRight

    reduce를 덧셈 함수로 알고 있는 사람들이 많은데, 대부분의 사이트에서 reduce 사용 예시를 덧셈으로 들고 있기 때문이다. 하지만 reduce는 알고보면 매우 강력한 메서드이다.

    reduce 메서드는 다음과 같이 사용한다. 배열.reduce( (누적값, 현잿값, 인덱스, 요소) => { return 결과 }, 초기값);

    이전값이 아니라 누적값이라는 것에 주의해야 한다. 누적값이기 때문에 다양하게 활용할 수 있다. 먼저 흔한 덧셈 예시를 보자.

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.reduce((acc, cur, i) => {
      console.log(acc, cur, i);
      return acc + cur;
    }, 0);
    // 0 1 0
    // 1 2 1
    // 3 3 2
    result; // 6

    acc(누적값)이 초깃값인 0부터 시작해서 return하는대로 누적되는 것을 볼 수 있습니다. 초깃값을 적어주지 않으면 자동으로 초깃값이 0번째 인덱스의 값이 된다.

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.reduce((acc, cur, i) => {
      console.log(acc, cur, i);
      return acc + cur;
    });
    // 1 2 1
    // 3 3 2
    result; // 6

    초깃값을 적었을 때와 안 적었을 때의 차이점을 확인하자.

     

    reduceRight는 reduce와 동작은 같지만 요소 순회를 오른쪽에서부터 왼쪽으로 한다는 점이 차이다.

    reduce는 배열 A → B

    reduceRight는 배열 A ← B

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.reduceRight((acc, cur, i) => {
      console.log(acc, cur, i);
      return acc + cur;
    }, 0);
    // 0 3 2
    // 3 2 1
    // 5 1 0
    result; // 6

    여기까지는 흔한 덧셈 예제이고 reduce는 덧셈 곱셈만을 위한 것이 아니다. 초깃값을 활용하여 어떤 일을 할 수 있는지 알아보자

    map과 filter과 같은 함수형 메서드를 모두 reduce로 모두 구현할 수 있다.

    위의 map 예제를 reduce로 만들어보자.

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.reduce((acc, cur) => {
      acc.push(cur % 2 ? '홀수' : '짝수');
      return acc;
    }, []);
    result; // ['홀수', '짝수', '홀수']

    초깃값을 배열로 만들고, 배열에 값들을 push하면 map과 같아진다. 이를 응용하여 조건부로 push를 하면 filter와 같아진다.

    다음은 홀수만 필터링하는 코드이다.

    const oneTwoThree = [1, 2, 3];
    result = oneTwoThree.reduce((acc, cur) => {
      if (cur % 2) acc.push(cur);
      return acc;
    }, []);
    result; // [1, 3]

    이와 같이 sort, every, some, find, findIndex, includes도 다 reduce로 구현 가능하다

     

    reduce는 비동기 프로그래밍을 할 때에도 유용하다.

    const promiseFactory = (time) => {
      return new Promise((resolve, reject) => {
        console.log(time); 
        setTimeout(resolve, time);
      });
    };
    [1000, 2000, 3000, 4000].reduce((acc, cur) => {
      return acc.then(() => promiseFactory(cur));
    }, Promise.resolve());
    // 바로 1000
    // 1초 후 2000
    // 2초 후 3000
    // 3초 후 4000

    초깃값을 Promise.resolve()로 한 후에, return된 프로미스에 then을 붙여 다음 누적값으로 넘기면 된다.

    프로미스가 순차적으로 실행됨을 보장할 수 있다.

    반복되는 모든 것에는 reduce를 쓸 수 있다는 것을 기억하자.

    map과 reduce 외에도, 배열의 메서드인 sort, filter, every, some, find, findIndex, includes 정도는 알아두면 좋다.

     

    reduce로 배열 메서드를 모두 구현해보자~

    반응형

    댓글

Designed by Tistory.