map, filter, reduce

JaeungE·2021년 7월 15일
0

JavaScript

목록 보기
10/16
post-thumbnail

JavaScript의 모든 배열 객체의 부모인 Array.prototype은 다양한 메서드를 가지고 있다.

이번에는 그중에서도 map(), filter(), reduce() 메서드에 대해서만 다뤄보려고 한다.

이 세 가지 메서드를 이용하면, 나머지 배열 메서드들을 대체할 수 있을 정도로 강력한 기능을 가지고 있으므로 꼭 알아두자!😆



map()

map() 메서드는, 기존에 있던 배열에 있던 요소들을 콜백 함수를 이용해서 다른 형식의 배열로 바꿀 수 있는 메서드다.

map() 메서드의 구문은 다음과 같다.

arr.map(callback(element, index, arr) { return r });

element 는 배열의 요소, index 는 배열의 인덱스, arr 배열 객체를 가리키고 return 값이 존재한다.

일단 어떻게 동작하는지 코드를 통해 알아보도록 하자!😄


const arr = [1, 2, 3, 4, 5];
const result = arr.map(element => element * 2);

console.log(arr); // 1, 2, 3, 4, 5
console.log(result); // 2, 4, 6, 8, 10

위 코드는 arr 배열의 각 요소에 2를 곱한 배열을 반환하는 코드이다.

보고나서 'forEach() 메서드랑 다른게 뭐지?` 라고 생각할 수도 있지만, 두 메서드의 차이는 바로 반환값에 있다.

map() 메서드는 forEach() 메서드와 달리, 원본 배열을 손상하지도 않을뿐더러 새로운 배열을 만들어서 반환하고, 심지어 새 배열의 각 요소에 반환 값도 할당해줄 수 있다는 점이다!😮

이를 이용하면 아래처럼 배열의 구조 자체를 바꾸는 것도 가능하다.


const names = ['Michel', 'Tommy', 'Rachel' ,'Johnson'];
const weights = [60, 87, 53, 72];
const heights = [168, 182, 160, 175];

const person = names.map((n, i) => ({name : n, weight : weights[i], height : heights[i]}));

console.log(person); 
/* 
 * [
 *   { name: 'Michel', weight: 60, height: 168 },
 *   { name: 'Tommy', weight: 87, height: 182 },
 *   { name: 'Rachel', weight: 53, height: 160 },
 *   { name: 'Johnson', weight: 72, height: 175 }
 * ]
 */

배열의 각 요소들을 조합해서 객체 정보를 담고있는 배열의 형태로 변한것을 볼 수 있다.

이처럼 map() 메서드를 활용하면 원본 배열을 손상하지 않고, 배열을 원하는 형식으로 변경할 수 있다!





filter()

filter() 메서드는 이름에서도 알 수 있듯이, 조건을 충족하는 요소만을 남겨서 반환하는 메서드이다.

filter() 메서드의 구문은 map() 과 동일하므로 따로 외울 필요는 없다.

그렇다면 코드를 통해 사용 방법부터 보도록 하자!😉


const arr = [];

for(let i = 1; i <= 20; i++){
    arr.push(i);
}

const even = arr.filter(num => num % 2 == 0);

console.log(even);
/*
 * [
 *   2,  4,  6,  8, 10,
 *   12, 14, 16, 18, 20
 * ]
 */

filter() 메서드를 이용해 1 ~ 20 까지의 정수를 담은 배열에서 짝수만을 뽑아낸 배열을 새로 만들어냈다.

이렇게 단순한 코드에서는 filter()의 필요성을 느끼지 못 할 수도 있지만, filter() 메서드는 map() 메서드와 조합이 가능하다는 장점이 있다.😲


const person = [
    {name : 'Joseph', age : 71},
    {name : 'Kim', age : 13},
    {name : 'Lee', age : 37},
    {name : 'Jassy', age : 54},
    {name : 'Mike', age : 46},
];

const result = person.filter(p => p.age >= 40).map(p => p.name);

console.log(result); // [ 'Joseph', 'Jassy', 'Mike' ]

위 코드는 나이가 40세 이상인 사람들의 이름만 모아서 배열로 만들어준다.

이처럼 filter()map()을 적절히 조합해서 사용하면, 원하는 배열을 간단하게 만들어 낼 수 있다!





reduce()

이름에서 알 수 있듯이, reduce() 메서드는 배열의 요소들을 더해나감으로써 하나의 값으로 만들어주는 메서드다.

여기서 하나의 값은 정수가 될 수도 있지만, 객체 혹은 배열이 되는 경우도 있으므로 기억해두자!😳

reduce() 메서드의 구문은 map()filter()와 비슷하지만 다른 점이 하나 있다.

arr.reduce(callback(accumulator, element, index, arr) { return r }, initValue));

element, index, arr,는 같은 역할을 하지만 accumulator 라는 매개 변수가 추가됐는데, 바로 이 accumulator 에 배열의 요소들을 더해서 하나의 값이 되도록 만들어 준다.

initValueaccumulator의 초깃값을 명시해주는 매개 변수다.

설명만 보면 복잡해 보인다...😅 배열의 모든 수를 더하는 간단한 예제를 보면서 이해해보자!


const arr = [];

for(let i = 0; i <= 10; i++){
    arr.push(i);
}

const sum = arr.reduce((acc, num) => acc += num, 0);

console.log(sum); // 55

reduce() 메서드를 이용해 배열에 저장되어있는 0부터 10까지의 정수를 모두 더해주는 코드이다.

이 정도의 예제는 굳이 reduce() 메서드를 사용할 필요가 없어보인다.. 라고 생각했다면 다음 예제를 보도록 하자!


const arr = "askmcosvausaowepksdnv".split('');

const alphabet = arr.reduce((obj, char) => {
    obj[char] = ++obj[char] || 1; 
    return obj;
}, {});

console.log(alphabet);
/*
 * {
 *   a: 3,
 *   s: 4,
 *   k: 2,
 *   m: 1,
 *   c: 1,
 *   o: 2,
 *   v: 2,
 *   u: 1,
 *   w: 1,
 *   e: 1,
 *   p: 1,
 *   d: 1,
 *   n: 1
 * }
 */

size 26의 배열을 별도로 만들어 주지 않고도, 문자열에서 특정 알파벳이 몇 번이 나왔는지 저장한 객체를 반환해주는 코드다.

이처럼 reduce()는 정수뿐만 아니라 객체 혹은 배열에도 값을 계속 누적해서 반환해줄 수 있는 강력한 기능을 가진 메서드다!





주의점

위에서 설명했던 세 개의 메서드 모두 좋은 기능을 가지고 있지만, 주의해야 할 점이 하나 있다!

바로 delete 키워드를 이용해 배열의 요소를 삭제했다면, 해당 요소에 대해서는 콜백 함수를 호출하지 않는다는 점이다.😢

하지만 보통 delete 키워드는 잘 사용하지도 않기도 하고, 그 외에 배열의 요소가 null 이거나 undefined 인 경우에도 정상적으로 동작하니 delete 키워드를 사용하지만 않는다면 문제될 일은 없다!





참고 자료

[Array.prototype.reduce() | MDN] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

[Array.prototype.filter() | MDN] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

[Array.prototype.map() | MDN] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map

0개의 댓글