9. 배열 고차 함수
고차 함수(Higher-Order-Function, HOF)는 함수를 인자로 전달받거나 함수를 반환하는 함수를 말한다.
9.1 Array.prototype.sort
배열의 요소를 적절하게 정렬한다.
원본 배열을 직접 변경한다.
기본적으로 오름차순(ascending)으로 요소를 정렬한다.
내림차순은 먼저 오름차순으로 정렬 후 순서를 뒤집는다.
1
2
3
4
5const fruits = ['바나나', '오렌지', '사과'];
fruits.sort();
console.log(fruits); //['바나나', '사과', '오렌지']
fruits.reverse(); // 내림차순(descending)
console.log(fruits); // ['오렌지', '사과', '바나나']문자열 정렬은 문제가 없으나 숫자 요소들을 정렬할 떄 문제 발생
배열의 요소를 일시적으로 문자열로 변환한 후 정렬한다. (Unicode 코드 포인트 순서)
정렬 순서를 정의하는 비교 함수를 인수로 전달해야한다.
1
2
3
4
5
6
7
8const points = [40, 100, 5, 1, 3, 28]
points.sort(function (a, b) { return a - b; });
// points.sort((a, b) => a - b);
console.log(points); // [1 , 3, 5, 28, 40, 100]
//
//
points.sort(function (a, b) { return b - a; }); //내림차순
// points.sort((a, b) => b - a);9.2 Array.prototype.forEach
for문을 대체할수 있는 메소드
배열을 순회하며 배열의 각 요소에 대하여 인수로 전달된 콜백 함수를 실행한다.
forEach 메소드의 콜백함수는 요소값, 인덱스, forEach 메소드를 호출한 배열,
즉 this를 전달 받을 수 있다.원본 배열을 변경하지 않는다. 하지만 콜백 함수가 원본 배열을 변경할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const numbers = [1, 2, 3];
let pows =[];
// for문
for (let i = 0; i < numbers.length i++) {
pows.push(numbers[i] ** 2);
}
console.log(pows); // [1, 4, 9]
//
// forEach 문
numbers.forEach(item => pows.push(item ** 2));
consoel.log(pows); //[1, 4, 9]
//
//
// 원본 배열 변경에 대해
const numbers = [1, 2, 3];
numbers.forEach((item, index, arr) => arr[index] = Math.pow(item, 2));
// 원본 배열을 직접 변경하려면 콜백함수의 3번째 인자를 사용한다.
//
// forEach 메소드의 반환값은 언제나 undifined
const result = [1, 2, 3].forEach(console.log);
console.log(result); //undifinedbreak, continue 문을 사용할 수 없다. (SyntaxError)
배열의 모든 요소를 모두 순회해야하며, 중간에 순회를 중단할 수 없다.
희소 배열의 존재하지 않는 요소는 순회 대상에서 제외된다.
for문에서는 undifined, forEach메소드에서는 무시
9.3 Array.prototype.map
- 배열을 순회하며 배열의 각 요소에 인수로 전달된 콜백 함수를 실행한다.
- 콜백 함수의 반환값들이 요소로 추가된 새로운 배열을 반환한다.
- 원본 배열은 변경되지 않는다.
- 배열을 순회하며 요소값을 다른값으로 맵핑하기 위한 함수
- map 메소드가 생성하여 반환하는 새로운 배열의 length는 map 메소드를 호출한 배열,
즉 this의 length와 반드시 일치한다. ( 1:1 mapping)1
2
3
4
5const numbers = [1, 4, 9];
const roots = numbers.map(item => Math.sqrt(item));
// const roots = numbers.map(Math.sqrt);
console.log(roots); // [1, 2, 3]
console.log(numbers); // [1, 4, 9]
9.4 Array.prototype.filter
- 배열을 순회하며 배열의 각 요소에 인수로 전달된 콜백 함수를 실행한다.
- 콜백 함수의 실행 결과가 true인 배열 요소의 값만을 추출한 새로운 배열로 반환한다.
- 반대로 특정요소를 제거하기위해 쓰기도 한다.
- 원본 배열은 변경되지 않는다.
1
2
3const numbers = [1, 2, 3, 4, 5];
const odds = numbers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]
9.4 Array.prototype.reduce
배열을 순회하며 콜백함수의 이전 반환값과 배열의 각요소에 인수로 전달된 콜백함수를 실행하여 하나의 결과값을 반환한다.
원본 배열은 변경되지 않는다.
첫번째 인수 - 콜백함수 , 두번째 인수 - 초기값을 전달받는다.
reduce 메소드의 콜백함수에는 4개의 인수 (초기값or콜백함수의 이전 반환값, 요소값, 인덱스, reduce 메소드를 호출한 배열(this))가 전달된다.
1
2
3
4
5
6
7
8
9// 1부터 4까지의 누적
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0); //10
//
// 평균 구하기
const values = [1 ,2 ,3, 4, 5];
const average = values.reduce((acc, cur, i, { length }) => {
return i === length - 1 ? (acc + cur) / length : acc + cur;
}, 0);
console.log(average); // 3map, filter, some, every, find와 같은 모든 배열 고차함수는 reduce로 구현할 수 있다.
두번째 인수로 전달하는 초기값은 옵션이다. (생략가능). 하지만 전달하는 것이 안전하다.
9.6 Array.prototype.some
- 배열을 순회하며 각 요소에 인수로 전달된 콜백 함수를 실행하여
그 결과가 하나라도 참이라면 true, 모두 거짓이라면 false를 반환한다. - 배열 요소 중에 콜백 함수를 통해 정의한 조건을 만족하는 요소가 1개 이상이 존재하는지 확인하여 그 결과를 불리언 타입으로 반환한다.
1
2
3
4
5let result = [5, 10, 15].some(item => item > 10);
cosnole.log(result); // true
//
fruits = ['apple', 'banana', 'orange'].some(item => item === 'apple');
console.log(fruits); // true
9.7 Array.prototype.every
- 배열을 순회하며 각 요소에 인수로 전달된 콜백 함수를 실행하여
그 결과가 모두 참이라면 true, 하나라도 거짓이면 false를 반환한다. - 콜백 함수를 통해 정의한 조건을 모두 만족하는지 확인하여 결과를 불리언 타입으로 반환한다.
1
2
3
4let result = [5, 10, 15].every(item => item > 3);
console.log(result); //true
result = [5, 10, 15 ].every(item => item > 10);
console.log(result); //false
9.8 Array.prototype.find
- ES6에서 새롭게 도입됌
- 콜백 함수를 실행하여 그 결과가 참인 첫번째 요소를 반환한다.
- 실행 결과가 참인 요소가 존재하지 않는다면 undifined를 반환한다.
1
2
3
4
5
6
7
8
9
10
11const users = {
{ id: 1, name: 'jung'},
{ id: 2, name: 'song'},
{ id: 3, name: 'yoo'},
{ id: 4, name: 'park'}
};
const result = users.find(item => item.id === 2);
console.log(result); // {id: 2 name: 'song'}
// 요소를 반환한다는 거에 주의하자.
// filter는 배열 반환 , find는 요소 반환
9.9 Array.prototype.findIndex
- ES6에서 새롭게 도입됌
- 콜백 함수를 실행하여 그 결과가 참인 첫번째 요소의 인덱스를 반환한다.
- 실행 결과가 참인 요소가 존재하지 않는다면 -1를 반환한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const users = {
{ id: 1, name: 'jung'},
{ id: 2, name: 'song'},
{ id: 3, name: 'yoo'},
{ id: 4, name: 'park'}
};
function predicate(key, value) {
//key와 value를 기억하는 클로저를 반환
return item => item[key] === value;
}
let index = users.findIndex(predicate('id', 2));
console.log(index); //1
index = users.findIndex(predicate('name', 'jung'));
console.log(index); //0
9.10 Array.prototype.flatMap
- ES10에서 새롭게 도입됌
- map을 통해서 생성된 새로운 배열을 평탄화한다.
- map 메소드와, flat 메소드를 순차적으로 실행하는 효과가 있다.
- 1단계만 평탄화 한다. (평탄화 깊이 지정 X)
1
2
3
4
5let arr = ['hello', 'young'];
console.log(arr.map(str => str.split('')).flat());
// ['h', 'e', 'l', 'l', 'o', 'y', 'o', 'u', 'n', 'g']
console.log(arr.flatMap(str => str.split('')));
// ['h', 'e', 'l', 'l', 'o', 'y', 'o', 'u', 'n', 'g']