27배열_고차 함수

이재철·2021년 10월 18일
0

javaScript

목록 보기
17/19
post-thumbnail

고차 함수(Higher-Order Function HOF)

  • 함수를 인수로 전달받고나 함수를 반환하는 함수
    • 외부 상태의 변경이나 가변(mutable) 데이터를 피하고 불변성(immutability)을 지향하는 함수형 프로그래밍에 기반

💡 함수형 프로그램

  • 순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임
  • 순수 함수를 통해 부수 효과를 최대한 억제

Array.prototype.sort

  • 배열의 요소를 정렬 (기본:오름차순)
  • 원본 배열을 직접 변경하며 정렬된 배열을 반환
const fruits = ['Banana', 'Orange', 'Apple'];
fruits.sort();
console.log(fruits); // ['Apple', 'Banana', 'Orange']

fruits.reverse();
console.log(fruits); // ['Orange', 'Banana', 'Apple']
  • 숫자 요소로 이루어진 배열을 정렬 시 주의
    • 유니코드 코드 포인트 순서를 따름
const points = [40, 100, 1, 5, 25, 10];
points.sort();
console.log(points); // [1, 10, 100, 2, 25, 40, 5]

['2', '10'].sort(); // ["10", "2"]
[2, 10].sort(); // [10, 2]

// ex1
const points = [40, 100, 1, 2, 5, 25, 10];
points.sort((a, b) => a - b);
console.log(points); // [1, 2, 5, 10, 25, 40, 100]

point.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]

// ex2

const todos = [ {id: 4, content:'A'},{id: 1, content:'B'},{id: 3, content:'C'}];

function compare(key) {
  return (a, b) => (a[key] > b[key] ? 1 : (a[key] < b[key] ? -1 : 0));
}

todos.sort(compare('id'));
console.log(todos);

/*
[{id: 1, content: 'B'},
{id: 3, content: 'C'},
{id: 4, content: 'A'}]
*/

Array.prototype.forEach

  • for 문을 대체할 수 있는 고차 함수
  • for 문과 달리 break, continue 문을 사용할 수 없음
    • 배열의 모든 요소를 빠짐없으 모두 순회하며 중간에 순회 중단 불가능
const numbers = [1, 2, 3];
const pows = [];

numbers.forEach(item => pows.push(item **2));
console.log(pows); [1, 4, 9]

[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]
*/

// 콜백함수를 통해 원본 배열을 변경
// 세 번째 매개변수 arr은 원본 배열인 numbers를 가리킴
numbers.forEach((item, index, arr) => {
 arr[index] = item ** 2;
});
console.log(numbers); // [1, 4, 9]

// forEach 메서드의 반환값은 언제나 undefined
const result = [1, 2, 3].forEach(console.log);
console.log(result); // undefined

Array.prototype.map

  • 자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출
    • 콜백 함수의 반환값들로 구성된 새로운 배열을 반환
    • 원본 배열은 변경되지 않음
const numbers = [1, 4, 9];
// 배열의 모든 요소를 순회하며 콜백 함수르 반복 호출 
const roots = numbers.map(item => Math.sqrt(item));

// map 메서드는 새로운 배열을 반환
console.log(roots); // [1, 2, 3]
// 원본 배열을 변경하지 않음
console.log(numbers); // [1, 4, 9]
  • 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치

Array.prototype.filter

  • 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환
  • 원본 배열은 변경되지 않음
const numbers = [1, 2, 3, 4, 5];
const odds = numbers.filter(item => item%2);
console.log(odds); // [1, 3, 5]
  • 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 같거나 작음

Array.prototype.reduce

  • 자신을 호출한 배열을 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출
    • 하나의 결과값을 만들어 반환
  • 원본 배열은 변경하지 않음
const sum = [1, 2, 3, 4].recue((accumulator, currentValue, index, array) => accumulator + currentValue, 0);
console.log(sum); // 10

// 평균구하기
const value = [1, 2, 3, 4, 5, 6];
const average = values.reduce((acc, cur, i { lenght }) => (i === length - 1 ? (acc+ cur) / length : acc + cur), 0);
console.log(average); // 3.5

// 최대값
const value = [1, 2, 3, 4, 5, 6];
const max = values.reduce((acc, cur) => ( acc > cur ? acc : cur),0);
console.log(max); // 5
// reduce 보다는 Math.max 메서드 사용
const max = Math.max(...values);
console.log(max); // 5

// 요소 중복 횟수 구하기
const fruits = ['banana', 'apple', 'orange', 'orange', 'apple'];

const count = fruits.reduce((acc, cur) => {
  acc[cur] = (acc[cur] || 0) + 1;
  return acc;
}, {});
/*
{banana: 1} => {banana:1, apple: 1} => {banana:1, apple: 1, orange:1} =>
{banana:1, apple: 1, orange:2} => {banana:1, apple: 2, orange:2}
*/
console.log(count); // {banana:1, apple: 2, orange:2}

// 중복된 요소 제거
const values = [1, 2, 1, 3, 5, 4, 4, 3, 4, 4];
const result = [...new Set(values)];
console.log(result); // [1, 2, 3, 4, 5]

// 빈 배열에 초기값을 전달하면 에러 발생 x
const sum = [].reduce.((acc, cur) => acc + cur, 0);
console.log(sum); // 0

// 객체의 특정 프로퍼티 값을 합산하는 경우 반드시 초기값을 전달
const products = [ {id: 1, price: 100}, {id: 2, price: 200}, {id: 3, price: 300}];

const priceSum = products.reduce((acc, cur) => acc + cur.price, 0);
console.log(priceSum);

Array.prototype.some

  • 배열의 요소 중에 콜백 함수를 통해 정의한 조건을 만족하는 요소가 1개이상 존재하는지 확인하여 그 결과를 불리언 타입으로 반환
    • 빈 배열인 경우 언제나 false를 반환
[5, 10, 15].some(item => item > 10); // true
[5, 10, 15].some(item => item < 0); // false

['apple', 'banana', 'mango'].some(item => item === 'banana'); // true
[].some(item => item > 3); // false

Array.prototype.every

  • 콜백 함수의 반환값이 모두 참이면 true, 단 한 번이라도 거짓이면 false 반환
    • 빈 배열인 경우 언제나 true 반환
[5, 10, 15].every(item => item > 3); // ture
[5, 10, 15].every(item => item > 10); // false

[].every(item => item > 3); // true

Array.prototype.find

  • 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소를 반환
    • 반환값이 true인 요소가 존재하지 않는다면 undefined를 반환
const users = [
  { id: 1, name: 'KKK'},
  { id: 2, name: 'QQQ'},
  { id: 3, name: 'DDD'},
  { id: 4, name: 'AAA'}
  ];

users.find(user => user.id === 2); // {id:2, name: 'QQQ'}

// filter 메서드는 배열을 반환
[1, 2, 2, 4].filter(item => item === 2); // [2, 2]
// find 메서드는 요소를 반환
[1, 2, 2, 3].find(item => item === 2); // 2

Array.prototype.findIndex

  • ES6 도입, 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소의 인덱스를 반환
    • 콜백 함수의 반환값이 true인 요소가 존재하지 않는다면 -1 반환
const users = [
  { id: 1, name: 'KKK'},
  { id: 2, name: 'QQQ'},
  { id: 3, name: 'DDD'},
  { id: 4, name: 'AAA'}
  ];

user.findIndex(user => user.id === 2); // 1
user.findIndex(user => user.name === 'QQQ'); // 1

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

users.findIndex(predicate('id', 2)); // 1

Array.prototype.flatMap

  • ES10 도입, map 메서드를 통해 생성된 새로운 배열을 평탄화함
    • 1 단계만 평탄화 할 수 있음
    • 중첨 배열으 ㅣ평탄화 깊이를 지정해야 하면 flatMap 메서드가 아닌 map 메서드와 flat 메서드를 각각 호출
const arr = ['hello', 'world'];
arr.map(x => x.split('')).flat();
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

arr.flatMap(x => x.split(''));
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

arr.map((str, index) => [index, [str, str.length]]).flat(2);
// [0, ['hello', 5]], [1, ['world', 5]]] => [0, 'hello', 5, 1, 'world', 5]

📖 참고도서 : 모던 자바스크립트 Deep Dive 자바스크립트의 기본 개념과 동작 원리 / 이웅모 저 | 위키북스

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글