[JavaScript] .map(), .filter(), .reduce() API 비교
JavaScript의 함수형 프로그래밍은 코드 가독성, 유지 관리 및 테스트에 이점이 있다. 함수형 프로그래밍 사고 방식에 도움이 되는 것 중 하나는 배열 처리 스타일 프로그래밍이다. 배열 처리 스타일 프로그래밍은 배열을 기본 데이터 구조로 사용하며, 배열의 요소에 대한 일련의 작업이 가능하다.
forEach : 배열의 항목에 접근
for 루프는 배열의 모든 항목을 접근, 반복하는데 사용된다.
forEach 역시 같은 역할을 하지만, for문 보다 더 간단하게 접근이 가능하다.
const strings = ['arielle', 'are', 'you', 'there'];
const capitalizedStrings = [];
for (let i = 0; i < strings.length; i += 1) {
const string = strings[i];
capitalizedStrings.push(string.toUpperCase());
}
console.log(capitalizedStrings);
const strings = ['arielle', 'are', 'you', 'there'];
const capitalizedStrings = [];
strings.forEach(function (string) {
capitalizedStrings.push(string.toUpperCase());
})
console.log(capitalizedStrings);
for 루프를 사용하면 각 배열의 항목에 접근을 하기 위해 인덱스로 접근을 해야하지만, forEach는 배열의 항목을 직접 반환한다.
map: 배열을 변환하여 새로운 배열 반환
// 너가 가지고 있는 정보
var officers = [
{ id: 20, name: 'Captain Piett' },
{ id: 24, name: 'General Veers' },
{ id: 56, name: 'Admiral Ozzel' },
{ id: 88, name: 'Commander Jerjerrod' }
];
// 필요한 정보
[20, 24, 56, 88]
만일 위와 같은 예시에서 각 사람의 id 정보만 배열에 담고 싶다면?
forEach를 사용해서 아래와 같이 배열을 초기화 후, push 연산을 사용해서 구현할 수 있다.
var officersIds = [];
officers.forEach(function (officer) {
officersIds.push(officer.id);
});
하지만, map을 사용하면 아래와 같이 코드를 더 간결하게 작성할 수 있다.
var officersIds = officers.map(function (officer) {
return officer.id
});
// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const officersIds = officers.map(officer => officer.id);
map은 callback 함수를 각각의 요소에 대해 한 번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다.
arr.map(callback(currentValue[, index[, array]])[, thisArg])
매개변수
- callback : 새로운 배열 요소를 생성하는 함수. 다음 세가지 인수를 가진다.
- currentValue : 처리할 현재 요소
- index(Optional) : 처리할 현재 요소의 인덱스
- array(Optional) : map()을 호출할 배열
- thisArg(Optional) : callback을 실행할 때 this로 사용되는 값
반환값
배열의 각 요소에 대해 실행한 callback의 결과를 모은 새로운 배열
새로운 결과 값을 반환한 배열은 항상 원래 배열(array)와 동일한 길이이다.
filter : 배열의 일부 요소만 추출하여 새로운 배열 반환
만약 배열에서 일부 요소(element)만 존재하는 배열이 필요하다면?
var pilots = [
{
id: 2,
name: "Wedge Antilles",
faction: "Rebels",
},
{
id: 8,
name: "Ciena Ree",
faction: "Empire",
},
{
id: 40,
name: "Iden Versio",
faction: "Empire",
},
{
id: 66,
name: "Thane Kyrell",
faction: "Rebels",
}
];
filter를 이용해서 한 배열(array)는 Rebel 파일럿을, 다른 배열(array)에는 Empire 파일럿을 간단하게 구현할 수 있다.
var rebels = pilots.filter(function (pilot) {
return pilot.faction === "Rebels";
});
var empire = pilots.filter(function (pilot) {
return pilot.faction === "Empire";
});
// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");
filter는 기본적으로 콜백 함수(callback function)이 true 를 리턴하면 현재 요소(element) 는 결과 배열에 있게 된다. False 를 반환하면 실행되지 않는다.
arr.filter(callback(element[, index[, array]])[, thisArg])
매개변수
- callback : 각 요소를 시험할 함수. true를 반환하면 요소를 유지하고, false를 반환하면 버린다. 다음 세가지 매개 변수를 받는다.
- element : 처리할 현재 요소
- index(Optional) : 처리할 현재 요소의 인덱스
- array(Optional) : filter를 호출한 배열
- thisArg(Optional) : callback을 실행할 때 this로 사용하는 값
반환값
테스트를 통과한 요소로 이루어진 새로운 배열. 어떤 요소도 테스트를 통과하지 못했으면 빈 배열을 반환한다.
reduce : 배열을 단일 값으로 변환
map과 filter 처럼 redouce 또한 배열의 각 요소(element)에 대해 콜백(callback)을 실행한다. 차이점은 reduce는 this callback(accumulator 누적값)의 결과를 한 배열(array) 요소에서 다른 배열(array)의 요소(element)로 전달한다.
accumulator는 거의 모든 것(interger, string, obejct 등)이 될 수 있다.
아래와 같이 파일럿 그리고 각 파일럿의 경력 년 수가 담긴 정보를 가진 배열(array)이 있다.
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14,
},
{
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30,
},
{
id: 41,
name: "Tallissan Lintra",
years: 16,
},
{
id: 99,
name: "Ello Asty",
years: 22,
}
];
reduce를 이용하면 모든 파일럿의 총 경력 년 수를 간단하게 알아볼 수 있다.
var totalYears = pilots.reduce(function (accumulator, pilot) {
return accumulator + pilot.years;
}, 0);
// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);
arr.reduce(callback[, initialValue])
매개변수
- callback : 배열의 각 요소에 대해 실행할 함수. 다음 네 가지 인수를 받는다.
- accumulator : 누산기는 콜백의 반환값을 누적한다. 콜백의 이전 반환 값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값이다.
- currentValue : 처리할 현재 요소
- currentIndex(Optional) : 처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작한다.
- arrray(Optional) : reduce()를 호출한 배열
- initialValue(Optional) : callback의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기 값을 제공하지 않으면 배열의 첫 번째 요소를 사용한다. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생한다.
반환값
누적 계산의 결과 값
Reference