한준호

[Modern javascript] 배열(2) 본문

Frontend/modern javascript

[Modern javascript] 배열(2)

igoman2 2021. 9. 14. 23:54
728x90

■ 배열 고차 함수

 

● 고차함수

- 함수를 인수로 전달받거나 함수를 반환하는 함수.

- 조건문과 반복문을 제거하고 변수의 사용을 억제하는 불변성 지향의 함수형 패러다임

 

◎ Array.prototype.sort

- 오름차순 정렬

- 일시적으로 요소를 문자열로 변환 후 유니코드 코드 포인트의 순서로 정렬하기 때문에 숫자를 정렬할 때는 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다.

- 기존에는 quicksort 알고리즘 기반이었지만 동일한 값의 요소가 중복되어 있을 때 초기 순서와 변경될 수 있는 불안정한 정렬 알고리즘이기 때문에 ES10 에서는 timesort 알고리즘을 사용하도록 바뀌었다.

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

// 숫자 배열의 내림차순 정렬. 비교 함수의 반환값이 0보다 작으면 b를 우선하여 정렬한다.
points.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]

// 숫자 배열에서 최대값 취득
console.log(points[0]); // 100

 

◎ Array.prototype.forEach

- 콜백 함수를 통해 반복하는 함수

- 원본 배열은 변경되지 않음 

  • 첫번째 인수: 요소
  • 두번재 인수: 인덱스
  • 세번째 인수: this(호출한 배열)
// forEach 메서드는 콜백 함수를 호출하면서 3개(요소값, 인덱스, this)의 인수를 전달한다.
[1, 2, 3].forEach((item, index, arr) => {
  console.log(`요소값: ${item}, 인덱스: ${index}, this: ${JSON.stringify(arr)}`);
});
/*
요소값: 1, 인덱스: 0, this: [1,2,3]
요소값: 2, 인덱스: 1, this: [1,2,3]
요소값: 3, 인덱스: 2, this: [1,2,3]
*/

 

◎ Array.prototype.map

- 배열의 모든 요소를 순회하면서 콜백 함수의 반환값들로 구성된 새로운 배열을 반환

- 원본 배열은 변경되지 않음

- forEach는 단순 반복용, 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 ]

 

◎ Array.prototype.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]

 

◎ Array.prototype.reduce

- 순회하면서 콜백 함수의 반환값을 다음 순회의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 반환

- 원본 배열은 변경되지 않음

  • 첫번째 인수: 콜백 함수
    • 초기값(이전 콜백 함수 반환값)
    • 호출한 배열의 요소
    • 인덱스
    • 호출한 배열
  • 두번째 인수: 초기값
// [1, 2, 3, 4]의 모든 요소의 누적을 구한다.
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0);

console.log(sum); // 10

reduce를 활용하여 다양한 함수를 구현할 수 있다.

  1. 평균 구하기
  2. 최대값 구하기
  3. 요소의 중복 횟수 구하기
  4. 중첩 배열 평탄화
  5. 중복 요소 제거

등등 직접 구현해보자.

 

◎ Array.prototype.some

- 배열의 요소 중 콜백 함수를 통해 정의한 조건을 만족하는 요소가 하나라도 있으면 true, 모두 거짓이면 false

- 빈 배열일 경우 false 반환

// 배열의 요소 중에 10보다 큰 요소가 1개 이상 존재하는지 확인
[5, 10, 15].some(item => item > 10); // -> true

// 배열의 요소 중에 0보다 작은 요소가 1개 이상 존재하는지 확인
[5, 10, 15].some(item => item < 0); // -> false

// 배열의 요소 중에 'banana'가 1개 이상 존재하는지 확인
['apple', 'banana', 'mango'].some(item => item === 'banana'); // -> true

// some 메서드를 호출한 배열이 빈 배열인 경우 언제나 false를 반환한다.
[].some(item => item > 3); // -> false

 

◎ Array.prototype.every

- some과 반대로 콜백 함수의 조건을 모두 만족하면 true, 하나라도 거짓이면 false

- 빈 배열일 경우 true 반환

// 배열의 모든 요소가 3보다 큰지 확인
[5, 10, 15].every(item => item > 3); // -> true

// 배열의 모든 요소가 10보다 큰지 확인
[5, 10, 15].every(item => item > 10); // -> false

// every 메서드를 호출한 배열이 빈 배열인 경우 언제나 true를 반환한다.
[].every(item => item > 3); // -> true

 

◎ Array.prototype.find

- 배열을 순회하면서 콜백 함수를 호출하여 true인 첫 번째 요소를 반환, 없으면 undefined 반환

- filter는 만족하는 모든 요소를 반환하므로 새로운 배열을 반환하지만 find는 요소값을 반환

// Array#filter는 배열을 반환한다.
[1, 2, 2, 3].filter(item => item === 2); // -> [2, 2]

// Array#find는 요소를 반환한다.
[1, 2, 2, 3].find(item => item === 2); // -> 2

 

◎ Array.prototype.findIndex

- find에서 반환된 요소의 index를 반환

const users = [
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' },
  { id: 2, name: 'Choi' },
  { id: 3, name: 'Park' }
];

// id가 2인 요소의 인덱스를 구한다.
users.findIndex(user => user.id === 2); // -> 1

// name이 'Park'인 요소의 인덱스를 구한다.
users.findIndex(user => user.name === 'Park'); // -> 3

// 위와 같이 프로퍼티 키와 프로퍼티 값으로 요소의 인덱스를 구하는 경우
// 다음과 같이 콜백 함수를 추상화할 수 있다.
function predicate(key, value) {
  // key와 value를 기억하는 클로저를 반환
  return item => item[key] === value;
}

// id가 2인 요소의 인덱스를 구한다.
users.findIndex(predicate('id', 2)); // -> 1

// name이 'Park'인 요소의 인덱스를 구한다.
users.findIndex(predicate('name', 'Park')); // -> 3

 

◎ Array.prototype.flatMap

- map과 flat을 순차적으로 실행하는 효과

const arr = ['hello', 'world'];

// map과 flat을 순차적으로 실행
arr.map(x => x.split('')).flat();
// -> ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

// flatMap은 map을 통해 생성된 새로운 배열을 평탄화한다.
arr.flatMap(x => x.split(''));
// -> ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
728x90
Comments