JavaScript - 자네 map & reduce에 대해서 알고 있나?

jodbsgh·2022년 10월 26일
0

🙋"JavaScript"

목록 보기
7/13
post-thumbnail

map & reduce란 무엇인가?🤔

자바스크립트 내장 메서드 중 하나로써 다양한 곳에 활용이 가능하다.

✔ map

let arr = [];

// 1. normal version
arr.map(function(요소, 인덱스, 배열){
	return 요소
});

// 2. arrow function version
arr.map((요소, 인덱스, 배열) => { return 요소 });

🕐map의 기본원리

반복문을 도려 배열 안의 요소들을 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, reduceRight

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
  1. acc(누적값)이 초기값인 0부터 시작하여 return하는대로 누적되는 것을 확인할 수 있다.
  2. 초기값을 적어주지 않으면 자동으로 초기값이 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]

🤸‍♂️비동기에도 유용한 reduce

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 정도 알아두면 배우 유용하다.


출처

원본보기

profile
어제 보다는 내일을, 내일 보다는 오늘을 🚀

0개의 댓글