Array에는 map()이나 filter(), join() 등의 메소드가 있다. 이 기능은 모두 reduce로도 구현이 된다.
또한 initialValue에 배열이나 객체를 주면 전역으로 객체변수를 하나 만드는 효과를 낼 수 있다.
reduce()
배열의 왼쪽부터 콜백 함수를 실행 후 누산한다.
배열.reduce(function(acc, cur, index, arr){ }[, initialValue])
1. 누산기 accumulator (acc)
2. 현재값 (cur)
3. 현재 인덱스 (index)
4. 원본 배열 (arr)
5. initialValue(optional: 사용해도 되고 안해도 됨) : callback의 최초 호출에서 첫 번째 인수에 제공하는 값이며 초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용한다. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생한다.
const numbers = [1, 2, 3, 4];
const result = numbers.reduce((num1, num2) => num1 + num2);
/*
1, 2 => 3 (배열값 1번째, 2번째부터 시작)
3, 3 => 6
6, 4 => 10
*/
console.log(result); // 10;
//------------------------------------
const result = numbers.reduce((num1, num2) => num1 + num2, 10);
/*
10, 1 => 11
11, 2 => 13
13, 3 => 16
16, 4 => 20
*/
console.log(result); // 20;
for문을 사용해서 풀 때보다 더 간단하고 권장하는 방법이다.
map, filter, reduce와 같은 함수는 순차적으로 값을 접근한다는 개념을 가져서 for문을 사용할 때 작성하는 반복문을 작성하지 않고 사용할 수 있다.
위의 덧셈 말고도 다른 산술 결과도 가능하다.
const nums = [1, 2, 3, 4];
const sumPlus = nums.reduce((num1, num2) => num1 + num2); //10
const sumMinus = nums.reduce((num1, num2) => num1 - num2); //-8
const sumMulti = nums.reduce((num1, num2) => num1 * num2); //24
[initvalue값이 없는 경우]
let numbs = [0, 1, 2, 3, 4].reduce(function(acc, cur, idx, arr){
console.log(`acc : ${acc}`);
console.log(`cur : ${cur}`);
console.log(`idx : ${idx}`);
console.log(" ");
return acc + cur;
});
//10
initialValue를 제공하지 않으면 reduce()는 인덱스 1부터 시작해서 콜백 함수를 실행하고 첫 번째 인덱스는 건너뛴다.
reduce()함수 호출시 initialValue 값이 없을 때,
- acc : 배열의 첫번째 값
- cur : 배열의 두번째 값
콜백 | acc | cur | idx | arr | 반환값 |
1번 | 0 | 1 | 1 | [0, 1, 2, 3, 4] | 1 |
2번 | 1 | 2 | 2 | [0, 1, 2, 3, 4] | 3 |
3번 | 3 | 3 | 3 | [0, 1, 2, 3, 4] | 6 |
4번 | 6 | 4 | 4 | [0, 1, 2, 3, 4] | 10 |
따라서 마지막 콜백 호출의 반환값인 10을 반환한다.
[initValue 값이 있는 경우]
let numbs = [0, 1, 2, 3, 4].reduce(function(acc, cur, idx, arr){
console.log(`acc : ${acc}`);
console.log(`cur : ${cur}`);
console.log(`idx : ${idx}`);
console.log(" ");
return acc + cur;
}, 10); //초기값 10을 줌.
//20
initialValue 를 (10) 설정하면 인덱스 0 에서 시작한다.
reduce()함수 호출시 initialValue 값이 있을 때,
- acc : initialValue
- cur : 배열의 첫번째 값
콜백 | acc | cur | idx | arr | 반환값 |
1번 | 10 | 0 | 0 | [0, 1, 2, 3, 4] | 10 |
2번 | 10 | 1 | 1 | [0, 1, 2, 3, 4] | 11 |
3번 | 11 | 2 | 2 | [0, 1, 2, 3, 4] | 13 |
4번 | 13 | 3 | 3 | [0, 1, 2, 3, 4] | 16 |
5번 | 16 | 4 | 4 | [0, 1, 2, 3, 4] | 20 |
따라서 마지막 콜백 호출의 반환값인 20을 반환한다.
[객체 배열에서 값 합산]
객체로 이루어진 배열에 들어있는 값을 합산하기 위해 반드시 initialValue 초기값을 줘야한다.
초기값을 줘야 각 항목이 모두 리듀서를 거치게 된다.
const initialValue = 0;
const list = [
{ x : 1 },
{ x : 2 },
{ x : 3 }
];
const listSum = list.reduce((acc, cur) => {
return acc + cur.x;
}, initialValue);
console.log(listSum); // 6
[중첩 배열 펼치기]
const arr = [
[0, 1],
[2, 3],
[4, 5]
];
const flatArr = arr.reduce((acc, cur) => [...acc, ...cur], []);
console.log(flatArr); // [0, 1, 2, 3, 4, 5]
[속성으로 객체 분류하기]
const members = [
{
name : 'nana',
age : 20
},
{
name : 'mimi',
age : 20
},
{
name : 'sora',
age : 22
}
];
function groupBy(objectArr, property){
return objectArr.reduce((acc, obj) => {
const key = obj[property];
if (!acc[key]){
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
const groupMember = groupBy(members, 'age');
/*
groupMember is :
{
20: [
{ name: 'nana', age: 20 },
{ name: 'mimi', age: 20 },
],
22 : [{ name: 'sora', age: 22 }]
*/
[객체 내의 값 인스턴스 개수 세기]
const names = ['nana', 'mimi', 'sora', 'nana', 'boa'];
const countNames = names.reduce((acc, cur) => {
if(name in allNames){
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {});
// countNames is :
// { 'nana': 2, 'mimi': 1, 'sora': 1, 'boa': 1}
[배열의 중복 항목 제거]
set 자료형을 이용해 new Set(arr) 하는 것이 더 간단하다.
reduce를 활용하는 방법 정도로 알아두자.
const arr = [1, 2, 1, 2, 3, 5, 6, 5, 3, 4, 4, 4, 4];
const result = arr.sort().reduce((acc, cur) => {
const length = acc.length;
if(legnth === 0 || acc[length - 1] !== cur){
acc.push(cur);
}
return acc;
}, []);
console.log(result); //[1, 2, 3, 4, 5]
[filter를 reduce로 구현]
[2, 4, 5, 6, 8].filter(value => value % 2 === 0) // [2, 4, 6, 8]
[2, 4, 5, 6, 8].reduce((acc, cur) => {
if(value % 2 === 0) acc.push(value);
return acc;
}, []);
// [2, 4, 6, 8]
[filter + map 조합을 reduce 하나로 구현]
[2, 4, 5, 6, 8]
.filter(val => val % 2 === 0)
.map(val => val * 10);
// [20, 40, 60, 80]
[2, 4, 5, 6, 8].reduce((acc, cur) => {
if(val % 2 === 0) acc.push(val * 10);
return acc;
}, []);
[2차원 배열 풀기]
[[1, 2], [3, 4]].reduce((acc, cur) => [...acc, ...val], []); //[1, 2, 3, 4]
[출처]
https://goddaehee.tistory.com/225
[JavaScript (4)] Javascript 제어문(1) - 조건문(if문, switch문)
[JavaScript (4)] Javascript 제어문(1) - 조건문(if문, switch문) 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ 자바스크립트 조건문 ] 입니다. : ) 0. 들어가기 앞서 특정 조건 만족 시(참인 경우) 실행하..
goddaehee.tistory.com
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Array.prototype.reduce() - JavaScript | MDN
reduce()** **메서드는 배열의 각 요소에 대해 주어진 **리듀서**(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.
developer.mozilla.org
[JS] 📚 배열 고차함수 🚇 reduce()
[reduce / reduceRight] 자바스크립트 Array.prototype 자바스크립트 배열을 반복해서 콜백 함수를 실행 후 하나의 결과 값을 반환 reduce 는 왼쪽 원소부터 콜백 함수를 실행 reduceRight 는 오른쪽 원소부터 콜
inpa.tistory.com
'개발 > Javascript' 카테고리의 다른 글
[JS] 자바스크립트의 중첩 함수 (0) | 2022.10.01 |
---|---|
[JS] mutable / immutable (1) | 2022.09.30 |
[JS] 문자열 비교하기 (1) | 2022.09.24 |
[JS] 전개 구문 (Spread syntax) (1) | 2022.09.23 |
[JS] 배열 정렬 방법 (오름차순, 내림차순) (1) | 2022.09.21 |