최근 Programmers, LeetCode 등에서 많은 알고리즘 문제를 풀어보고 있다. 그러다 보면 배열 내 인자들을 순회 홰야 하는 경우가 자주 있다. 이럴 때마다 난 for문
OR while문
을 사용해서 대부분 문제를 접근했다. 하지만 열심히 문제를 풀고 난 후 훨씬 간결한 타 유저들의 정답 코드를 보게 되면 감탄과 좌절을 동시에 하게 되는 경우가 많다. 코드가 짧기 때문에 무조건 베스트라고 할 수는 없지만, 간결한 코드를 작성하는 이들이 공통으로 자주 사용하는 메서들에 대해 더 깊이 있는 이해력을 갖추는 게 좋겠다고 판단되었다. 그래서 map
, filter
, reduce
에 대해 공부를 해봤고, 그 내용을 잊어버리지 않기 위해 이 글에 정리해두었다.
map()
은 배열 내 모든 요소에 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다. 즉, 배열 내 모든 요소에 공통적인 함수를 적용하고 싶을 때 사용하기 적합합니다.
const nations = ['Korea', 'USA', 'Japan'];
const newNations = nations.map(function(nation) {
return nation + ' 입니다';
});
console.log(newNations) //output: ['Korea 입니다', 'USA 입니다', 'Japan 입니다']
nations
배열이 있음 " 입니다"
가 추가된 새로운 배열 작성하기 위해 map
메서드 사용함newNations
로 반환됨const nums = [1, 2, 3, 4, 5];
const newNums = nums.map(num => num * 2);
console.log(newNums); //output: [2, 4, 6, 8, 10]
filter()
는 순회하는 배열 내 모든 요소 중 함수의 테스트를 통과한 요소들만 모아 새로운 배열로 반환합니다. 배열 내 특정 조건에 부합한 요소만 찾고 싶을 때 사용하기 적합합니다.
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'
으로 수정하면 문자 요소만 반환 가능 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
에 넣음reduce()
는 배열 내 각 요소에 주어진 함수를 수행하고 하나의 결과값을 반환합니다. 배열 내 모든 요소를 더하는 등 배열 내 요소들 기준 새로운 하나의 값을 만들고 싶을 때 사용하기 적합합니다.
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
값 더해줌acc
값으로 자동 업데이트 됨 acc
값만 반환함 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]