보통 배열 내 인자들을 차례로 순회할 때 for문을 많이 사용한다.
하지만 조금만 JavaScript를 살펴보면 for문보다 더 유용하고 간결하게 코드를 작성하게 해주는 메서드를 만날 수 있다.
그래서 오늘은 배열에 사용하는 메서드 중에서도 비슷한 기능을 하는 세 함수 filter, reduce, map에 대해 알아보겠다.
filter, reduce, map 세 개 모두 ES6에서 추가된 메소드이다.그리고 배열 타입에 사용하며, 각 요소들을 파라미터로 받아 작동한다는 공통점이 있다.그렇다면 어떤 점에서 차이가점이 있고 어떤 상황에서 사용하는게 좋을지 알아보도록 하자
❗ Map
map()은 배열 각 요소에 대하여 주어진 함수를 수행한 결과를 모아 새로운 배열을 반환하는 메소드이다.섭씨 -> 화씨, 숫자 -> 문자 등 요소 들에게 일괄적으로 함수를 적용하고 싶을 때 사용하기 적합하다.map()에 대한 예시를 먼저 살펴보자
const numbers = [1,2,3,4,5];
const numberMap = numbers.map(val => val * 2);
console.log(numbersMap);
// [2,4,6,8,10]
map()의 사용 방법으로는 위 예제처럼 매개변수로 배열의 인자를 받고, 해당 인자에 어떤 변화를 준 뒤 반환하는 식으로 사용한다.
위에서는 배열의 인자, val이라는 하나의 매개 변수만 사용했지만 사실 map은 3개의 매개변수를 가지고있다.
매개변수의 이름과 설명은 아래와 같다.
- value : 현재 요소
- index : 요소의 인덱스
- array : map()을 호출한 원본 배열 (위 예제에서는 numbers의 배열)
** 해당 매개변수 중 index와 array는 필수 입력이 아님
const numbers = [1,2,3];
const numbersMap = numbers.map((value,index,array) => {
console.log("value : " + value, "index: " + index, "array: " + array);
return value * 2;
});
console.log(numbersMap);
// value : 1 index: 0 array: 1,2,3 -> index 0번의 value는 1이고 해당 배열의 값에는 1,2,3이 담겨있음
// value : 2 index: 1 array: 1,2,3 -> index 1번의 value는 2이고 해당 배열의 값에는 1,2,3이 담겨있음
// value : 3 index: 2 array: 1,2,3 -> index 2번의 value는 3이고 해당 배열의 값에는 1,2,3이 담겨있음
// [2, 4, 6] // numbers의 배열의 value에 *2 연산을 거친 후의 결과 값
❗ filter
filter()는 배열 각 요소에 대하여 주어진 함수의 결과값이 true인 요소를 모아 새로운 배열을 반환하는 메소드이다.
map이 내부 함수의 리턴 값이 문자, 숫자, 배열 등으로 다양한 타입이 가능하다면,
filter()는 오직 boolean 타입만 반환한다는 특징이 있다.
그리고 리턴 값이 true인 경우에만 배열에 추가하기 때문에 중복 제거처럼 조건에 맞는 특정 요소들만 새 배열에 넣고 싶은 경우에 사용하면 적합하다.
filter()에 대한 예제를 살펴보자
const name = ['jiwoo', 'jihyun', 'minji', 'jaehwan']
const nameFilter = name.filter(word => word.length > 5);
console.log(nameFilter)
// ['jihyun', 'jaehwan']
filter도 map과 마찬가지로 3개의 매개변수를 갖고있다.
매개 변수의 이름과 설명은 아래와 같다.
- value : 현재 요소
- index : 요소의 인덱스
- array : filter()을 호출한 원본 배열 (위 예제에서는 name의 배열)
** map()과 동일하게 filter()도 index와 array는 필수 입력 요소가 아니다.
const name = ['jiwoo', 'jihyun', 'minji', 'jaehwan']
const nameFilter = name.filter((value, index, array) => {
console.log("value : " + value, "index: " + index, "array: " + array);
return value.length > 5;
});
console.log(nameFilter)
// value : jiwoo index: 0 array: jiwoo,jihyun,minji,jaehwan
// value : jihyun index: 1 array: jiwoo,jihyun,minji,jaehwan
// value : minji index: 2 array: jiwoo,jihyun,minji,jaehwan
// value : jaehwan index: 3 array: jiwoo,jihyun,minji,jaehwan
// ['jihyun', 'jaehwan']
❗ reduce
reduce() 메소드는 위에서 알아본 두 메소드보다 이해가 조금 더 어렵다.
하지만 그 이해하고 난다면 다양한 상황에서 활용할 수 있는 강력한 메소드임에는 틀림이 없다.
우선 reduce()는 배열 각 요소에 대하여 reducer 함수를 실행하고, map과 filter와 달리 배열이 아닌 하나의 결과값을 반환한다는 차이점이 있다.
reduce()예시를 한 번 살펴보자.
const numbers = [1,2,3,4];
const numberSum = numbers.reduce((acc, cur) => {
console.log(acc, cur);
return numbersSum = acc + cur;
});
console.log(numbersSum)
// 1 2
// 3 3
// 6 4
// 10
위의 예시는 reduce 함수에서 값을 계속 누적하여 갖고 있는 누산기인 acc와 현재 요소인 cur을 매개변수로 하여 모든 요소의 합을 반환하는 로직이다.
console.log(acc, cur)의 결괏값을 차례로 살펴보면 어떻게 계산기 누적되고 있는지 알 수 있다.
누산기라는 개념이 생소할 수 있는데 간단하게 표현하자면 reduce 함수를 수행하면서 생기는 값을 임시적으로 보관하는 형태이다. 만약 reduce 함수를 이용해 모든 배열을 더한 값을 알고 싶다면 0번째, 1번째... n번째 요소를 계산한 값을 보관하고 있는것이다.
또한 reduce에는 초기값이라는 생소한 값을 입력할 수 있다.
아래 예시의 경우 함수의 끝에 10이라는 숫자가 추가된 걸 볼 수 잇는데, 이처럼 초기값은 숫자부터 배열까지 다양한 값을 입력할 수 잇다.
초기값을 입력하게 되면 배열의 첫 번째 요소부터가 아니라 초기값부터 계산이 시작된다.
아까와는 달리 맨 첫 번째 acc값이 10이 된 것을 확인하자 !
const numbers = [1,2,3,4];
const numberSum = numbers.reduce((acc, cur) => {
console.log("acc : " + acc, "cur : " + cur);
return numbersSum = acc + cur;
},10)
console.log("numbersSum : " + numbersSum)
// acc : 10 cur : 1
// acc : 11 cur : 2
// acc : 13 cur : 3
// acc : 16 cur : 4
// numbersSum : 20
그리고 예시에서 사용한 2가지를 포함하여 총 4개의 매개변수를 가지고 있다.
- accumulator : 리턴한 값을 저장하는 변수, 초기값을 지정한 경우에는 초기값부터 시작.
- currentValue : 현재 요소
- currentIndex : 요소의 인덱스
- array : reduce()를 호출한 원본 배열
** currentIndex와 array는 필수적으로 입력하지 않아도 된다.
const numbers = [1,2,3,4];
const numbersSum = numbers.reduce((accumulator, currentValue, currentIndex, array) =>{
console.log("accumulator: " + accumulator);
console.log("currentValue : " + currentValue);
console.log("currentIndex : " + currentIndex);
console.log("array : " + array);
console.log(" ====================== " );
return accumulator + currentValue;
}, 10);
console.log("numbersSum : " + numbersSum);
// accumulator: 10
// currentValue : 1
// currentIndex : 0
// array : 1,2,3,4
// ======================
// accumulator: 11
// currentValue : 2
// currentIndex : 1
// array : 1,2,3,4
// ======================
// accumulator: 13
// currentValue : 3
// currentIndex : 2
// array : 1,2,3,4
// ======================
// accumulator: 16
// currentValue : 4
// currentIndex : 3
// array : 1,2,3,4
// ======================
// numbersSum : 20
reduce()는 매개변수로 들어가는 누산기라는 개념이 낯설고, 문법도 다른 메소드에 비해 까다롭기 때문에 초반에 이해하기엔 비교적 어렵다. 하지만 그 만큼 익혀두면 유용하게 사용하는 메소드이다.
특히 map(), filter()와 같은 함수형 메소드를 reduce()만으로 구현할 수 있다.
아래는 위에서 작업한 map(), fiilter() 예제를 reduce를 사용하여 재작성한 코드이다.
👀 map() -> reduce()
//map()
const numbers = [1,2,3,4,5];
const numberMap = numbers.map(val => val * 2);
console.log(numbersMap);
// [2,4,6,8,10]
//reduce()
const numbers = [1,2,3,4,5];
const numbersReduce = numbers.reduce((acc, cur) => {
acc.push(cur * 2);
return acc;
}, {}};
console.log(numbersReduce);
// [2,4,6,8,10]
👀 filter() -> reduce()
//filter()
const name = ['jiwoo', 'jihyun', 'minji', 'jaehwan'];
const nameFilter = name.filter(word => word.length > 5);
console.log(nameFilter)
// ['jihyun', 'jaehwan']
//reduce()
const name = ['jiwoo', 'jihyun', 'minji', 'jaehwan'];
const nameReduce = name.reduce((acc, cur) => {
if(cur.length >5)
acc.push(cur);
return acc;
}, []);
console.log(nameReduce);
// ['jihyun', 'jaehwan']
이처럼 reduce()는 활용도가 높은 함수이기 때문에 다양한 목적으로 사용할 수 있다.
활용 방법은 공식 문서에서 자세히 다루고 있으니 보는것을 추천한다.
출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
'자바스크립트 - Vanilla JS' 카테고리의 다른 글
[자바스크립트 / Vanilla JS] 스프레드 연산자 (Spread Operator) (1) | 2022.09.21 |
---|---|
[자바스크립트 / Vanilla JS] 클래스 (class) 총정리 (2) | 2022.09.19 |
[자바스크립트 / Vanilla JS] 디스트럭처링이란 ? (객체 디스트럭처링, 배열 디스트럭처링) (1) | 2022.09.13 |
[자바스크립트 / Vanilla JS] 함수 기본값 인수 (0) | 2022.09.13 |
[자바스크립트 / Vanilla JS] 화살표 함수란 무엇일까 ? (0) | 2022.09.07 |