자바스크립트 내장 메서드 중 하나로써 다양한 곳에 활용이 가능하다.
let arr = [];
// 1. normal version
arr.map(function(요소, 인덱스, 배열){
return 요소
});
// 2. arrow function version
arr.map((요소, 인덱스, 배열) => { return 요소 });
반복문을 도려 배열 안의 요소들을 1대1 로 짝지어 주는 것.
즉, 매핑이라고도 표현함.
어떻게 짝 지어 줄 것인가를 정의한 함수를 메서드의 인자로 넣어주면 된다.
const oneTwoThree = [ 1, 2, 3 ];
let result = oneTwoThree.map((v) => {
console.log(v);
return v;
});
oneTwoThree; // [1, 2, 3]
result; // [1, 2, 3]
oneTwoThree === result // false
위의 코드를 통해서 알 수 있는 점은, map을 실행하는 배열과 결과로 출력된 배열이 서로 다르다는 것이다. 기존 배열을 수정하지 않고 새로운 배열을 만들어낸다. 단, 배열 안에 객체가 들어있는 경우, 객체는 공유된다.
result = oneTwoThree.map((v)=>{
return v + 1;
});
result; //['1', '2', '3']
result = oneTwoThree.map((v) => {
if(v % 2) {
return '홀수';
}
return '짝수';
});
result; // ['홀수', '짝수', '홀수']
규칙적인 배열만 반환할 수 있는게 아니라, 함수 안에 적어준대로 반환할 수 있기 때문에 자유도가 높다.
정리
map은 배열을 1대1로 짝짓지만, 기존 객체를 수정하지는 않는 메서드다.
reduce 메서드는 다음과 같이 사용한다.
배열.reduce((누적값, 현재값, 인덱스, 요소) => {return 결과}, 초기값);
이전 값이 아니라 누적값이라는 것에 주의해야한다. 누적값이기 때문에 다양하게 활용할 수 있다.
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번째 인덱스의 값이 된다
// 초기값을 설정하지 않은 경우
result = oneTwoThree.reduce((acc, cur, i) => {
console.log(acc, cur, i);
return acc + cur;
});
// 1 2 1
// 3 3 2
result; // 6
reduceRight는 reduce와 동작은 같지만 요소 순회를 오른쪽에서부터 왼쪽으로 한다는 점에서 차이가 있다.
// 초기값을 설정하지 않은 경우
result = oneTwoThree.reduce((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로 만들어보기
//result = oneTwoThree.map((v) => {
// if (v % 2) {
// return '홀수';
// }
// return '짝수';
//});
//result; // ['홀수', '짝수', '홀수']
result = oneTwoThree.reduce((acc, cur) => {
acc.push(cur % 2 ? '홀수' : '짝수');
return acc;
}, []);
result; // ['홀수', '짝수', '홀수']
초기값을 배열로 만들고, 배열에 값들을 push하면 map과 같아진다. 이를 응용해 조건부로 push를 하면 filter와 같아진다.
// 홀수만 필터링하는 코드
result = oneTwoThree.reduce((acc, cur) => {
if (cur % 2) acc.push(cur);
return acc;
}, []);
result; // [1, 3]
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 정도 알아두면 배우 유용하다.