- [27.9] 배열 고차 함수
- 고차 함수는 함수를 인수로 전달받거나 함수를 반환하는 함수를 말한다.
- 자바스크립트의 함수는 일급 객체이므로 함수를 값처럼 인수로 전달할 수 있으며 반환할 수도 있다.
- 고차 함수는 외부 상태의 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에 기반을 두고 있다.
- 함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임이다.
- 함수형 프로그래밍은 결국 순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환이라고 할 수 있다.
- Array.prototype.sort
- sort 메서드는 배열의 요소를 정렬한다.
- 원본 배열을 직접 변경하며 정렬된 배열을 반환한다.
- const fruits = ['Banana', 'Orange', 'Apple'];
// 오름차순(ascending) 정렬
fruits.sort( );
// sort 메서드는 원본 배열을 직접 변경한다.
console.log(fruits); // ['Apple', 'Banana', 'Orange']
- const fruits = ['Banana', 'Orange', 'Apple'];
- 원본 배열을 직접 변경하며 정렬된 배열을 반환한다.
- sort 메서드의 기본 정렬 순서는 유니코드 코드 포인트의 순서를 따른다.
- 배열의 요소가 숫자 타입이라 할지라도 배열의 요소를 일시적으로 문자열로 변환한 후 유니코드 코드 포인트의 순서를 기준으로 정의한다.
- 숫자 요소를 정렬할 때는 sort 메서드에 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다.
- const points = [40, 100, 1, 5, 2, 25, 10];
// 숫자 배열의 오름차순 정렬. 비교 함수의 반환값이 0보다 작으면 a를 우선하여 정렬한다.
points.sort((a, b) => a - b);
console.log(points); // [1, 2, 5, 10, 25, 40, 100]
// 숫자 배열에서 최소/최대값 취득
console.log(points[0], points[points.length - 1]); // 1 100
// 숫자 배열의 내림차순 정렬. 비교 함수의 반환값이 0보다 작으면 b를 우선하여 정렬한다.
points.sort((a, b) => b -a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]
// 숫자 배열에서 최소/최대값 취득
console.log(points[points.length - 1], points[0]); // 1 100
- const points = [40, 100, 1, 5, 2, 25, 10];
- sort 메서드는 배열의 요소를 정렬한다.
- Array.prototype.forEach
- 앞에서 살펴보았듯이 함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임이다.
- forEach 메서드는 for 문을 대체할 수 있는 고차 함수다.
- forEach 메서드는 반복문을 추상화한 고차 함수로서 내부에서 반복문을 통해 자신을 호출한 배열을 순회하면서 수행해야 할 처리를 콜백 함수로 전달받아 반복 호출한다.
- const numbers = [1, 2, 3];
const pows = [ ];
// forEach 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출한다.
numbers.forEach(item => pows.push(item ** 2));
console.log(pows); // [1, 4, 9] - 위 예제의 경우 forEach 메서드는 numbers 배열의 모든 요소를 순회하며 콜백 함수를 반복 호출한다.
- numbers 배열의 요소가 3개이므로 콜백 함수도 3번 호출된다.
- 이때 콜백 함수를 호출하는 forEach 메서드는 콜백 함수에 인수를 전달할 수 있다.
- const numbers = [1, 2, 3];
- forEach 메서드는 반복문을 추상화한 고차 함수로서 내부에서 반복문을 통해 자신을 호출한 배열을 순회하면서 수행해야 할 처리를 콜백 함수로 전달받아 반복 호출한다.
- forEach 메서드는 원본 배열(forEach 메서드를 호출한 배열, 즉 this)을 변경하지 않는다.
- 콜백 함수를 통해 원본 배열을 변경할 수는 있다.
- forEach 메서드의 두 번째 인수로 forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다.
- class Numbers {
numberArray = [ ];
multiply(arr) {
arr.forEach(function (item) {
this.numberArray.push(item*item);
}, this); // forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달
}
}
const numbers = new Numbers( );
numbers.multiply([1, 2, 3]);
console.log(numbers.numberArray); // [1, 4, 9] - class Numbers {
numberArray = [ ];
multiply(arr) {
// 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조한다.
arr.forEach(item => this.numberArray.push(item*item));
}
}
const numbers = new Numbers( );
numbers.multiply([1, 2, 3]);
console.log(numbers.numberArray); // [1, 4, 9]
- class Numbers {
- forEach 메서드는 for 문과는 달리 break, continue 문을 사용할 수 없다.
- Array.prototype.map
- map 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다.
- 그리고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.
- 이때 원본 배열을 변경되지 않는다.
- const numbers = [1, 4, 9];
// map 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출한다.
// 그리고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.
const roots = numbers.map(item => Math.sqrt(item));
// 위 코드는 다음과 같다.
// const roots = numbers.map(Math.sqrt);
// map 메서드는 새로운 배열을 반환한다.
console.log(roots); // [1, 2, 3]
// map 메서드는 원본 배열을 변경하지 않는다.
console.log(numbers); // [1, 4, 9]
- const numbers = [1, 4, 9];
- forEach 메서드와 map 메서드의 공통점은 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다는 것이다.
- 하지만 forEach 메서드는 언제나 undefined를 반환하고, map 메서드는 콜백 함수의 반환값들로 구성된 새로운 배열을 반환하는 차이가 있다.
- map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치한다.
- 즉, map 메서드를 호출한 배열과 map 메서드가 생성하여 반환한 배열은 1:1 매핑한다.
- Array.prototype.filter
- filter 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다.
- 그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다.
- 이때 원본 배열을 변경되지 않는다.
- const numbers = [1, 2, 3, 4, 5];
// filter 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출한다.
// 그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다.
// 다음의 경우 numbers 배열에서 홀수인 요소만 필터링한다(1은 true로 평가된다).
const odds = numbers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]
- const numbers = [1, 2, 3, 4, 5];
- filter 메서드는 자신을 호출한 배열에서 필터링 조건을 만족하는 특정 요소만 추출하여 새로운 배열을 만들고 싶을 때 사용한다.
- filter 메서드가 생성하여 반환한 새로운 배열의 length 프로퍼티 값은 filter 메서드를 호출한 배열의 length 프로퍼티 값과 같거나 작다.
- Array.prototype.reduce
- reduce 메서드는 자신을 호출한 배열을 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출한다.
- 그리고 콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다.
- 이때 원본 배열을 변경되지 않는다.
- // 1부터 4까지 누적을 구한다.
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0);
console.log(sum); // 10
- // 1부터 4까지 누적을 구한다.
- reduce 메서드를 호출할 때는 언제나 초기값을 전달하는 것이 안전하다.
'[자바스크립트]' 카테고리의 다른 글
[JavaScript/DeepDive]29.Math (0) | 2021.06.08 |
---|---|
[JavaScript/DeepDive]28.Number (0) | 2021.06.07 |
[JavaScript/DeepDive]27.배열(2) (0) | 2021.06.04 |
[JavaScript/DeepDive]27.배열(1) (0) | 2021.06.04 |
[JavaScript/DeepDive]26.ES6 함수의 추가 기능 (0) | 2021.06.01 |