[JS] 고차 함수 (higher-order function)

2022. 3. 4. 02:18Front-end/JavaScript

고차 함수란?

하나 이상의 함수를 매개변수로 취하거나 함수를 결과로 반환하는 함수다.

매개변수로 전달되는 함수는 콜백 함수(Callback function)다.


대표 배열 조작 메서드

  • 임의 정렬 : Array.sort(callback function)
  • 반복 작업 : Array.forEach()
  • 콜백 함수 결과 배열 반환 : Array.map()
  • 조건을 만족하는 값 하나만 반환 : Array.find()
  • 조건을 만족하는 값 배열로 반환 : Array.filter()
  • 누적 결과 값 반환 : Array.reduce()

 

sort() 문제와 한계점

문제 : 일의 자리 4가 10의 자리보다 뒤쪽에 정렬

원인 : sort 메서드로 정렬될 때 배열의 요소가 일시적으로 문자열로 변경되어 발생

let nums = [1, -1, 4, 0, 2, 3, 10, 20, 12];

console.log(nums.sort());
// [ -1, 0, 1, 10, 12, 2, 20, 3, 4 ]
console.log(nums.reverse());
// [ 4, 3, 20, 2, 12, 10, 1, 0, -1 ]

한계점 : 대소문자 구분 없이 정렬하고 싶지만 대소문자 구분되어 정렬된다

let fruits = ["apple", "orange", "Banana", "banana"];

console.log(fruits.sort());
// [ 'Banana', 'apple', 'banana', 'orange' ]
console.log(fruits.reverse());
// [ 'orange', 'banana', 'apple', 'Banana' ]

 

sort(callback function)으로 문제 해결

sort() 함수의 매개변수로 함수를 넣어 고차 함수를 이용한 정렬 수행이 가능하다

let ascending_num = function (x, y) {
  return x - y;
};

let descending_num = function (x, y) {
  return y - x;
};

let nums = [1, -1, 4, 0, 2, 3, 10, 20, 12];

console.log(nums.sort(ascending_num)); // [ -1, 0, 1, 2, 3, 4, 10, 12, 20 ]
console.log(nums.sort(descending_num)); // [ 20, 12, 10, 4, 3, 2, 1, 0, -1 ]

let ascending_str = function (x, y) {
  x = x.toUpperCase();
  y = y.toUpperCase();

  if (x > y) return 1;
  else if (y > x) return -1;
  else return 0;
};

let descending_str = function (x, y) {
  x = x.toUpperCase();
  y = y.toUpperCase();

  if (x < y) return 1;
  else if (y < x) return -1;
  else return 0;
};

let fruits = ["apple", "orange", "Banana", "banana"];

console.log(fruits.sort(ascending_str)); // [ 'apple', 'Banana', 'banana', 'orange' ]
console.log(fruits.sort(descending_str)); // [ 'orange', 'Banana', 'banana', 'apple' ]

위 코드의 ascending_num, descending_num 함수와 ascending_str, descending_str 함수를 공통으로 사용하기

let ascending_order = function (x, y) {
  if (typeof x === "string") x = x.toUpperCase();
  if (typeof y === "string") y = y.toUpperCase();

  return x > y ? 1 : -1;
};

let descending_order = function (x, y) {
  if (typeof x === "string") x = x.toUpperCase();
  if (typeof y === "string") y = y.toUpperCase();

  return x < y ? 1 : -1;
};

console.log(nums.sort(ascending_order)); // [ -1, 0, 1, 2, 3, 4, 10, 12, 20 ]
console.log(nums.sort(descending_order)); // [ 20, 12, 10, 4, 3, 2, 1, 0, -1 ]
console.log(fruits.sort(ascending_order)); // [ 'apple', 'banana', 'Banana', 'orange' ]
console.log(fruits.sort(descending_order)); // [ 'orange', 'Banana', 'banana', 'apple' ]

 

forEach()

  • 배열 요소 별 콜백 함수 각각에 실행 : Array.forEach(function(value, index, array){})
  • value : 배열 요소, index : 배열 위치, array : 배열
let arr = [1, 2, 3];

// use for loop
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

// use forEach
arr.forEach(function (i) {
  console.log(i);
});

 

map()

  • 배열 요소 별 함수 호출 및 결과를 배열로 반환 : Array.map(function(value, index, array){})
  • value : 배열 요소, index : 배열 위치, array : 배열
let arrr = [1, 2, 3, 4, 5];

// use for loop
let use_for = [];
for (let i = 0; i < arrr.length; i++) {
  use_for.push(arrr[i] * 2);
}
console.log(use_for); // [ 2, 4, 6, 8, 10 ]

// use map
let use_map = arrr.map((i) => {
  return i * 2;
});
console.log(use_map); // [ 2, 4, 6, 8, 10 ]

 

find()

  • 콜백 함수의 조건을 만족하는 하나의 값만 반환 : Array.find(function(value, index, array){})
  • value : 배열 요소, index : 배열 위치, array : 배열
let users = [
  { name: "kh", age: 26, job: true },
  { name: "ys", age: 25, job: false },
  { name: "mc", age: 24, job: false },
];

let find_job = users.find((user) => {
  return user.job === false;
});
console.log(find_job); // { name: 'ys', age: 25, job: false }

let find_age = users.find((user) => {
  return user.age >= 20;
});
console.log(find_age); // { name: 'kh', age: 26, job: true }

 

filter()

  • 콜백 함수의 조건을 만족하는 값을 배열로 반환 : Array.filter(function(value, index, array){})
  • value : 배열 요소, index : 배열 위치, array : 배열
let users = [
  { name: "kh", age: 26, job: true },
  { name: "ys", age: 25, job: false },
  { name: "mc", age: 24, job: false },
];

let filter_job = users.filter((user) => {
  return user.job === false;
});
console.log(filter_job);
// [
//   { name: 'ys', age: 25, job: false },
//   { name: 'mc', age: 24, job: false }
// ]

let filter_age = users.filter((user) => {
  return user.age >= 20;
});
console.log(filter_age);
// [
//   { name: 'kh', age: 26, job: true },
//   { name: 'ys', age: 25, job: false },
//   { name: 'mc', age: 24, job: false }
// ]

 

reduce()

  • 요소 별 함수 수행 누적 결과 값 반환 : Array.reduce(function(previousValue, currentValue, currentIndex, array){})
  • previousValue : 이전 값, currentValue : 배열 요소, currentIndex : 배열 위치, array : 배열

initialValue를 설정하지 않으면 배열의 첫 번째 요소부터 시작한다

 

반응형