JavaScript
Array.prototype.reduce()
.reduce()
- 배열의 각 요소에 대해 주어진 reducer 함수를 실행, 하나의 결과값을 반환
- 콜백 최초의 호출 때 acc, curr 의 값 ↓↓
* initialValue 없을 경우
acc = 배열의 첫 번째 값 = array[0]
curr = 배열의 두 번째 값 = array[1]
* initialValue 있는 경우
acc = initialValue 값
curr = 배열의 첫 번째 값 = array[0]
- initialValue를 제공하지 않으면 reduce()는 index 1부터 시작해 callback 함수를 실행하고 첫 번째 index는 건너 뛴다. initialValue를 제공하면 index 0에서 시작
초기값(initialValue)를 넣는 게 더 안전한 이유 ↓↓(아래 코드 예제 有)
- 빈 배열에 initialValue제공하지 않으면 TypeError 발생
- 빈 배열에 initialValue 제공되면 그 단독 값을 callback 호출 없이 반환
- 요소 1개인 배열에 initialValue 가 없다면 그 단독 값을 callback 호출 없이 반환
기본 구문
arr.reduce(callback[, initialValue])
매개 변수
1. callback
callback의 인수는 4가지가 있다.
- accumulator(=acc) : 콜백의 반환값을 누적, 콜백 이전의 반환값 또는 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값
- currentValue(=curr) : 처리할 현재 요소
- currenIndex(=index) (Optional) : 처리할 현재 요소의 인덱스
- array (Optional) : reduce()를 호출한 배열
2. initailValue (Optional)
callback의 최초 호출에서 첫 번째 인수에 제공하는 값, 초기값을 제공하지 않으면 배열의 첫 번째 요소를 반환. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생한다.
반환 값
누적 계산의 결과 값
예제1 : reduce() 작동 방식
[ 모든 값의 합산 ]
* 초기값을 안넣어서 배열의 첫 번째 값 0 이 acc로 미리 들어감.
-> 초기값 없는 경우 index는 1 부터 시작
이유는 acc = ___빈값___ curr = 1 / (index=0) 인 경우가 생략되었기 때문 같다
let a =[1,2,3,4,5].reduce(function(acc,curr,index,arr){
console.log(` acc = ${acc} curr = ${curr} index = ${index} arr= ${arr}`)
return acc+curr;
})
console.log(a)
예제 2 : 초기값 0 넣어보기
acc = 0 (초기값)
curr = 1 (배열의 첫 번째 값)
* 초기값 있기 떄문에 index 는 0 부터 시작
let a =[1,2,3,4,5].reduce(function(acc,curr,index,arr){
console.log(`acc = ${acc} curr = ${curr} index = ${index} arr= ${arr}`)
return acc+curr;
},0)
console.log(a)
초기값 10 넣으면
let a =[1,2,3,4,5].reduce(function(acc,curr,index,arr){
console.log(`acc = ${acc} curr = ${curr} index = ${index} arr= ${arr}`)
return acc+curr;
},10)
console.log(a)
예제 3 : 화살표 함수 이용 해보기
일반 함수
let a =[1,2,3,4,5].reduce(function(acc,curr,index,arr){
return acc+curr;
},0)
console.log(a) //15
화살표 함수 (Arrow Function)
'function' 삭제 / => 추가
let a =[1,2,3,4,5].reduce((acc,curr,index,arr)=>{
return acc+curr;
},0)
console.log(a) //15
reduce 일반 함수와 arrow 함수 주의 사항
function(){} -> {}꼭 쓰고 {} 대괄호가 쓰이면 return 써야함
()=>{} -> {} - Optional , {} 대괄호를 쓴다면 return 필수
옳은 방법
1. function(){return }
2. (()=> )
3. (()=>{return {})
let a =[1,2,3,4,5].reduce((acc,curr,index,arr)=>{return acc+curr},0)
let b =[1,2,3,4,5].reduce(function(acc,curr,index,arr){return acc+curr},0)
console.log(a) //15
console.log(b) //15
function solution1(a, b) {
let answer = a.reduce((acc,curr,i)=>acc += curr*b[i], 0);
return answer;
}
function solution2(a, b) {
let answer = a.reduce((acc,curr,i)=>{acc += curr*b[i]}, 0);
return answer; //undefined
}
function solution3(a, b) {
let answer = a.reduce((acc,curr,i)=>{return acc += curr*b[i]}, 0);
return answer;
}
function solution4(a, b) {
let answer = a.reduce(function(acc,curr,i){return acc += curr*b[i]}, 0);
return answer;
}
console.log(solution1([1,2,3],[4,5,6]));
console.log(solution2([1,2,3],[4,5,6]));
console.log(solution3([1,2,3],[4,5,6]));
console.log(solution4([1,2,3],[4,5,6]));
예제 4 : 객체 배열에서의 값 합산
let iniValue=0;
let sum = [{x:1}, {x:2},{x:3}].reduce((acc,curr)=>{
console.log(`acc = ${acc} curr = ${curr} curr.x = ${curr.x}`)
return acc+curr.x;
},iniValue);
console.log(sum)
curr (현재 처리할 값) 의 .x
x라는 property 값 = curr.x
curr 쓰면 [Object Object]가 뜨게 된다.
여기서 initialValue값을 없애면?
첫 번째 acc의 값이 array[0] = 배열의 첫 번째 요소가 되기 때문에 [Object Object]를 들고와버린다.
ex)
let iniValue=0;
let sum = [{x:1}, {x:2},{x:3}].reduce((acc,curr)=>{
console.log(`acc = ${acc} curr = ${curr} curr.x = ${curr.x}`)
return acc+curr.x;
});
console.log(sum)
예제 5 : 초기값(initialValue)를 넣는 게 더 안전한 이유
- 요소 1개인 배열에 initialValue 가 없다면 그 단독 값을 callback 호출 없이 반환
- 빈 배열에 initialValue 제공되면 그 단독 값을 callback 호출 없이 반환
- 빈 배열에 initialValue제공하지 않으면 TypeError 발생
let max = (acc,cur) => Math.max(acc.x, cur.x);
let max2 = (max,cur) => Math.max(max,cur);
console.log([{x:10}, {x:20}].reduce(max)) // 20
console.log([{x:10} ].reduce(max)) // {x:10}
console.log([ ].reduce(max,1)) // 빈배열 + iniValue = iniValue
console.log([ ].reduce(max)) //빈배열 + no iniValue =TypeError
? max 함수에서 acc.x 를 쓴 이유는 이해가 안간다. undefined로 나오는데 (혹시 아시는 분,,,? )
이러한 점을 개선한 .map + .reduce 사용
let max2 = (acc,cur) => Math.max(acc,cur);
console.log([{x:10}, {x:20}].map(ele=>ele.x)); // [10,20]
console.log([{x:10}, {x:20}].map(ele=>ele.x).reduce(max2,-Infinity)) //20
** Math.pow() 란 거듭제곱 !
// Infinitive 양의 무한대 <-> -Infinitive 음의 무한대
console.log(1/0) //Infinity
console.log(-1/0) //-Infinity
console.log(Math.pow(10,1000)); // Infinity 10 을 1000번 제곱해라 === Infinitive
예제 6 : 중첩 배열 펼치기 flatten
let flattened = [[0,1],[2,3],[4,5]].reduce((acc,curr)=>{
return acc.concat(curr);
},[])
console.log(flattened)
시도해본 다른 방법 ( reduce((acc,curr)=>{return acc.concat(curr))} ) 아직 요것뿐
let flattened = [[0,1],[2,3],[4,5]].reduce((acc,curr)=>{
return acc.concat(curr);
}) //여기에 초기값0 을 넣으면 오류. 배열을 처리해서 그런듯
let a =[]; //대신 초기값 [] 를 넣으면 가능
console.log(flattened)
console.log([[0,1],[2,3],[4,5]].concat()); // concat은 앞 배열, () 배열 을 합침
console.log(a.concat(flattened)); /// 요렇게
console.log([[0,1],[2,3],[4,5]].join());
console.log([[0,1],[2,3],[4,5]].join(''));
예제 7 : 배열의 중복 항목 제거
let arr = [1,2,1,2,3,4,5,6,4,3,2,3,6,4,6,2];
let result = arr.sort().reduce((acc,curr)=>{
const length = acc.length;
if(length==0 || curr != acc[length-1]){
acc.push(curr);
}
return acc;
},[]); //초기값 []빼먹지 않기
console.log(result)
예제 8 : 객체 내의 값 인스턴스 개수 세기
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let coutedNames = names.reduce(function (acc,curr){
if(curr in acc){ // acc 배열 안에 curr 현재 요소 값이 있으면 ++;
acc[curr]++; // <- acc 배열 안에 curr라는 property 만듦
}else{
acc[curr] = 1;
}
return acc;
},{})
console.log(coutedNames)
'Javascript' 카테고리의 다른 글
JavaScript 자바스크립트 String.fromCharCode() 사용법 , 예제 String.fromCodePoint와 차이점 (0) | 2021.05.23 |
---|---|
JavaScript 자바스크립트 String.fromCodePoint() 사용법 예제 String.fromCharCode 차이 (0) | 2021.05.23 |
JavaScript 자바스크립트 .concat() 사용법, 연습 예제 (0) | 2021.05.21 |
JavaScript 자바스크립트 재귀함수 (0) | 2021.05.21 |
JavaScript 자바스크립트 String 함수 .repeat() 사용하기 (0) | 2021.05.21 |