본문 바로가기

Javascript

JavaScript 자바스크립트 .reduce() 사용법, 연습 예제

반응형

 

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)

 

 

 

 

 

 

반응형