-
TIL-2024.02.15 - JS - 고차함수와 Reduce> 기초/Javascript 2024. 2. 15. 21:50
------- 고차함수 란?
고차함수:
- JS에서 함수는 일급 객체이므로 함수를 값처럼 인수로 전달할수 있고, 반환 가능.
- 고차 함수는 외부 상태의 변경이나 가변 데이터를 피하고 immutability (불변성)을 지향하는 함수형 프로그래밍에 기반을 둠
------- Reduce 란?
Reduce 특징:
- 고차함수: 함수를 인수로 전달받거나 함수를 반환하는 함수
- 순수함수: 동일한 인자가 들어오면 항상 같은 값이 나와야하고 return 값으로만 소통하고 데이터베이스 호출이나 HTTP 호출 등 외부의 데이터 구조를 변형하는 호출을 허용하지 않는 함수
설명:
- 자신을 호출한 배열의 모든 요소를 순회하며, 인수로 전달받은 콜백 함수를 반복 호출.
- 콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환.
- 원본 배열은 변경하지 않음
- 첫번째 인수로 콜백함수, 두번째 인수로 초기값 전달 받음.
- 첫번째 인수인 콜백함수는 4개의 인수 (초기값/콜백함수의 이전 반환값, reduce를 호추한 배열의 요소값-index, 배열 자체)가 전달
예제:
const sum = [1,2,3,4].reduce((accumulator,currentVal,index,array) => accumulator + currentVal, 0); console.log(sum) // 10 >> 이러한 과정을 반복하여 reduce 메서드는 하나의 결과값 반환
예제 설명:
구분 콜백 함수에 전달되는 인수 콜백 함수의 반환값 accumulator currentVal index array 첫 번째 순회 0 (초기값) 1 0 [1,2,3,4] 1(accumulator +
currentVal)두 번째 순회 1 2 1 [1,2,3,4] 3(accumulator +
currentVal)세 번째 순회 3 3 2 [1,2,3,4] 6(accumulator +
currentVal)네 번쨰 순회 6 4 3 [1,2,3,4] 10(accumulator +
currentVal)사용 예제:
// 1. 평균 구하기 const average = [1,2,3,4,5,6].reduce((acc, cur, index , {length}) => { return index === length - 1 ? (acc + cur) / length : acc + cur; }, 0); console.log(average) // 3.5 // 2. 최대값 구하기 const max = [1,2,3,4,5].reduce((acc, cur) => acc > cur ? acc: cur, 0 ) console.log(max) // 5 // 3. 요소의 중복 횟수 구하기 const countFruits = ['banana', 'apple', 'orange', 'orange', 'apple'].reduce((acc, cur) => { // 1. 첫번째 순회 시, acc는 초기값인 {} 이고, cur은 첫번째 요소인 'banana' // 2. 초기값으로 전달받은 빈 객체에 요소값인 cur을 프로퍼티 키로, 요소의 갯수를 프로퍼티 값으로 할당 // 3. 만약 프로퍼티 값이 undefined이면 프로퍼티 값을 1로 초기화한다. acc[cur] = (acc[cur] || 0 ) + 1 return acc }, {}} // 4. 중첩 배열 평탄화 (.flat) const flatten = [1,[2,3],[4,5]].reduce((acc,val) => acc.concat(val),[]); console.log(flatten) // [1,2,3,4,5] // 5. 중복 요소 제거 const duplicated = [ 1,2,1,3,5,4,5,3,4,4].reduce((acc,val,i , array) => array.indexOf(val) === i ?[...acc, val] : acc, []) // 1. i가 val의 인덱스와 같으면, 처음 순회하는 요소. // 2. i가 val의 인덱스와 다르면, val은 중복된 요소
이와 같이, 다양하게 reduce를 활용할 수 있다. Reduce 에서 초기값 (두번째로 인수) 생략 가능하지만, 언제나 초기값을 전달하는 것이 안전하다.
왜?
const price = [ {id: 1 , price: 100}, {id: 2 , price: 200}, {id: 3 , price: 300} ]; > 초기값 X // 1. 첫번째 순회시, acc = {id: 1 , price: 100}, cur = {id: 2 , price: 200} // 2. 두번째 순회시, acc = 300, cur = {id: 3 , price: 300} // 2. 두번째 순횐시, acc 함수에 객체가 아닌 숫자 전달, thus undefined. return price.reduce((acc, cur) => acc.price + cur.price); > 초기값 O // 1. 첫번째 순회시, acc = 0, cur = {id: 1 , price: 100} // 2. 두번째 순회시, acc = 100, cur = {id: 2 , price: 200} // 2. 세번째 순회시, acc = 300, cur = {id: 3 , price: 300} return price.reduce((acc, cur) => acc.price + cur.price , 0);
'> 기초 > Javascript' 카테고리의 다른 글
TIL-2024.02.21 - JS - 실행 컨텍스트-1 (0) 2024.02.21 TIL-2024.02.20 - JS - 스코프 (0) 2024.02.20 TIL-2024.02.19 - JS - 변수 - 2. 호이스팅 관점에서 본 var, let, const (0) 2024.02.19 TIL-2024.02.18 - JS - 변수 - 1. 변수 원리 (0) 2024.02.18 002_ECMAScript 중요 사항 (지속 추가 예정) (0) 2022.07.05