[JS] map, filter, reduce에 대한 이해

손규성·2022년 10월 9일
1

javascript

목록 보기
1/8
post-thumbnail

서론


최근 Programmers, LeetCode 등에서 많은 알고리즘 문제를 풀어보고 있다. 그러다 보면 배열 내 인자들을 순회 홰야 하는 경우가 자주 있다. 이럴 때마다 난 for문 OR while문을 사용해서 대부분 문제를 접근했다. 하지만 열심히 문제를 풀고 난 후 훨씬 간결한 타 유저들의 정답 코드를 보게 되면 감탄과 좌절을 동시에 하게 되는 경우가 많다. 코드가 짧기 때문에 무조건 베스트라고 할 수는 없지만, 간결한 코드를 작성하는 이들이 공통으로 자주 사용하는 메서들에 대해 더 깊이 있는 이해력을 갖추는 게 좋겠다고 판단되었다. 그래서 map, filter, reduce에 대해 공부를 해봤고, 그 내용을 잊어버리지 않기 위해 이 글에 정리해두었다.



1. Array.prototype.map()


간단한 설명

map()은 배열 내 모든 요소에 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다. 즉, 배열 내 모든 요소에 공통적인 함수를 적용하고 싶을 때 사용하기 적합합니다.


Example A:

const nations = ['Korea', 'USA', 'Japan'];

const newNations = nations.map(function(nation) {
  return nation + ' 입니다';
});

console.log(newNations) //output: ['Korea 입니다', 'USA 입니다', 'Japan 입니다']
  • 국가명이 들어있는 nations 배열이 있음
  • 각 element의 끝에 " 입니다"가 추가된 새로운 배열 작성하기 위해 map 메서드 사용함
  • callback 함수가 모든 element에 적용되고, 새로운 배열newNations로 반환됨

Example B:

const nums = [1, 2, 3, 4, 5];

const newNums = nums.map(num => num * 2);

console.log(newNums); //output: [2, 4, 6, 8, 10]
  • 당연히 string이 아닌 숫자와도 사용 가능함
  • 화살표 함수로 표현 가능하며, 이런 경우 더 간결하게 작성 가능함


2. Array.prototype.filter()


간단한 설명

filter()는 순회하는 배열 내 모든 요소 중 함수의 테스트를 통과한 요소들만 모아 새로운 배열로 반환합니다. 배열 내 특정 조건에 부합한 요소만 찾고 싶을 때 사용하기 적합합니다.


Example A:

const info = [1, 2, 'James', 3, 4, 'Korea'];

const nums = info.filter(function(x) {
  if (typeof x === 'number') return x;
}); 

console.log(nums); //output: [1, 2, 3, 4]
  • 숫자와 문자 요소가 혼합되어 있는 info라는 배열이 존재함
  • filter에 조건문을 통해 typeof가 'number'인 요소만 새 배열nums에 넣음
  • 마찬가지로 조건문을 typeof x === 'string'으로 수정하면 문자 요소만 반환 가능

Example B:

const words = ['armistice', 'pack', 'fossil', 'lawsuit', 'cafe', 'disclosure'];

const result = words.filter(word => word.length === 4);

console.log(result); // ['pack', 'cafe']
  • 기존 배열 words 내 요소 중 length가 4인 경우만 새로운 배열 result에 넣음
  • 마찬가지로 화살표 함수로 표현해 더 간결한 코드 작성 가능함


3. Array.prototype.reduce()


간단한 설명

reduce()는 배열 내 각 요소에 주어진 함수를 수행하고 하나의 결과값을 반환합니다. 배열 내 모든 요소를 더하는 등 배열 내 요소들 기준 새로운 하나의 값을 만들고 싶을 때 사용하기 적합합니다.


Example A:

const nums = [1, 2, 3, 4, 5, 6, 7];

const newNums = nums.reduce(function(acc, cur) {
  return acc + cur;
}, 0);

console.log(newNums); //output: 28
  • 여기서 acc 는 accumulator (누산기) , cur은 current (현재 값), 마지막 0은 initial value (초기 값)
  • 초기 값 0에서 배열 순회하며 cur값 더해줌
  • callback 함수 1회 실행 후 결과는 acc값으로 자동 업데이트 됨
  • 1 ~ 7을 모두 더한 28, 즉 배열 순회 후 최종 acc값만 반환함
  • 주의: 초기 값을 제공하지 않으면 배열의 첫 번째 요소 사용함

Example B:

const arrs = [[0, 1], [2, 3], [4, 5]]

const newArr = arrs.reduce((acc, curr) => acc.concat(curr), []);

console.log(newArr); //output: [0, 1, 2, 3, 4, 5]
  • 화살표 함수로도 구현 가능함


콜백 함수 활용하기


각 메서드 안에 입력되는 함수를 별도로 작성하고, 필요할 떄마다 입력해서 사용하는 방법도 있다. 예를 들어 아래 문자열과 숫자가 혼합되어 있는 배열 words가 존재한다고 가정해보자.

여기서 숫자 요소만 빼둔 새로운 배열을 반환하기 위해서 아래 코드를 작성할 수 있다.

const words = ['James', 'global', 2, 3, 4, 'agriculture'];

const result = words.filter(num => typeof num === 'number');

위에서 봤듯이 filter() 메서드에 화살표 함수를 넣어 작성하면 숫자 요소만 새로운 배열에 넣어 반환할 수 있다. 다만, 여러 배열에서 똑같이 숫자인 요소만 뽑아내야 한다면, 동일한 화살표 함수를 여러번 반복해서 작성해야 한다는 단점이 존재한다.

이런 경우 각각의 요소가 숫자임을 판별하는 함수를 별도로 작성해두고, 이를 filter()에 호출해서 사용할 수 있다.

const isNumber = function(element) {
  if (typeof element === 'number') {
    return true;
  }
}; 

const words = ['James', 'global', 2, 3, 4, 'agriculture'];
const words2 = ['apple', 'banana', 4, 8, 1, 'Korea'];

console.log(words.filter(isNumber));
//output: [2, 3, 4]

console.log(words2.filter(isNumber));
//output: [4, 8, 1]
profile
블로그 이사 → https://sqsung.tistory.com/

0개의 댓글