[JavaScript]고차함수(High-Order Function)

LMH·2022년 11월 17일
2
post-thumbnail

오늘은 고차 함수(High-Order function)에 대해서 정리하고자 합니다. 이전 포스팅에서 배열 메소드를 정리할 때 filter, map, reduce와 같은 콜백함수를 전달인자로 받는 메소드들에 대해 정리를 했었습니다. 이 함수들은 단순히 값을 받아 값을 리턴 하는 것이 아닌 함수를 전달인자로 받거나 함수를 리턴하는 형태를 가지고 있습니다. 이런 함수들을 고차함수라고 합니다.

고차함수

  • 함수의 전달인자로 받는 함수(콜백함수를 전달인자로 받는 함수)
  • 함수를 리턴하는 함수

일급객체

자바스크립트에서 함수는 일급 객체입니다. 일급객체의 특징은 다음과 같습니다.

  • 변수에 할당 가능
  • 다른 함수의 전달인자로 전달 가능
  • 다름 함수의 결과로 리턴 가능(커링 함수)

즉, 함수는 문자열, 숫자 같은 다른 데이터 처럼 사용이 가능합니다.

추상화

함수는 하나의 기능의 단위이며 고차함수는 개발자들이 개발하기 편리하도록 미리 만들어 놓은 로직이라 할 수 있습니다. 이는 복잡한 것을 압축해서 핵심만 추출하는 추상화의 단계를 거친 것 입니다. 예를들어 자동차의 작동원리는 정확히 몰라도 운전하는 법만 알면 자동차를 이용하는데 전혀 문제가 없습니다. 마찬가지로 추상화된 고차함수를 활용한다면 복잡한 문제를 간단하게 해결할 수 있습니다.

자주 사용하는 고차함수

배열은 많은 양의 데이터를 편리하게 다를 수 있는 데이터 타입입니다. 배열에 고차함수를 사용하여 배열 내의 요소를 효율적으로 조작할 수 있습니다. 오늘은 Araay.prototype 객체에 내장되어 있는 내장메소드 filter, map, reduce에 대해 정리하겠습니다.

filter

특정 조건에 맞는 배열의 요소만 추출하여 새로운 배열을 생성합니다. filter 매소드의 retrun 값을 조건으로 true를 리턴하는 요소들만 모은 새로운 배열을 생성합니다. 아래의 코드는 arr 배열의 홀수 요소만 필터링하는 코드입니다.

// arr.filter(callback(element, index, array) { 조건 })
const arr = [1, 2, 3, 4, 5, 6];

const oddArr = arr.filter(function(el) {
	return el%2 === 1;
})
const evenArr = arr.filter(function(el, index) {
	return el%2 === 0;
})
console.log(oddArr); // [1, 3, 5]
console.log(evenArr); // [0: 1,1: 3,2: 5]
// index 값을 줄경우 각 요소에 index 값이 붙습니다.

map

map 메소드는 기존의 배열을 변경하여 똑같은 길이의 새로운 배열을 생성합니다.

// arr.map(callback(element, index, array) { })

const arr = [1, 2, 3, 4, 5, 6];

const doubleArr = arr.map(function(el) {
	el = el * 2
	return el
})
console.log(doubleArr); // [2, 4, 6, 8, 10, 12]

const doubleArr = arr.map(function(el, index) {
	el = el * 2 + index
	return el
})
console.log(doubleArr); // [2, 5, 8, 11, 14, 17]
// index 값을 이용하여 배열의 요소를 변경할 수 도 있습니다.

reduce

reduce는 각 배열의 요소를 콜백함수에 맞게 응축하여 새로운 배열을 형성합니다. 이 메소드는 처음봐서는 잘 이해가 되지 않을 수 있습니다. 초기값이 주어지지 않을 경우 배열의 첫번째 요소를 초기값으로 하여 콜백함수를 실행하고, 콜백함수의 return 값이 다시 콜백함수의 첫번째 요소로 들어가며 반복됩니다.

// arr.reduce(callback(accumulator, currentValue, index, arry) { }, initialValue)

const arr = [1, 2, 3, 4, 5, 6];

const sum = arr.reduce(function(acc, cur) {
	return acc + cur;  
})
console.log(sum); // 21
// 콜백함수 첫번쨰 호출 acc : 1,  cur : 2 -> return : 3
// 콜백함수 두번쨰 호출 acc : 3,  cur : 3 -> return : 6
// 콜백함수 세번쨰 호출 acc : 6,  cur : 4 -> return : 10
// 콜백함수 네번쨰 호출 acc : 10,  cur : 5 -> return : 15
// 콜백함수 다섯쨰 호출 acc : 15,  cur : 6 -> return : 21
// 콜박함수가 종료되며 return된 값이 sum에 할당

const sum2 = arr.reduce(function(acc, cur) {
	return acc + cur;  
}, 10) // 초기값을 10으로 설정
console.log(sum2); // 31
// 콜백함수 첫번쨰 호출 acc : 10,  cur : 1 -> return : 11
// 콜백함수 두번쨰 호출 acc : 11,  cur : 2 -> return : 13
// 콜백함수 세번쨰 호출 acc : 13,  cur : 3 -> return : 16
// 콜백함수 네번쨰 호출 acc : 16,  cur : 4 -> return : 20
// 콜백함수 다섯쨰 호출 acc : 20,  cur : 5 -> return : 25
// 콜백함수 여섯쨰 호출 acc : 25,  cur : 6 -> return : 31
// 콜박함수가 종료되며 return된 값이 sum에 할당

위에서 보셨다 싶히 특정 조건의 요소만 추출하고자 한다면 filter 메소드(배열 길이 변경)를 사용하며 배열 각각의 요소에 새로운 로직을 추가하고 싶은 경우 map 메소드(배열 길이 동일)를 사용하며 배열의 요소를 돌며 반복된 작업이 필요한 경우 reduce 메소드를 사용하면 됩니다.

여러 고차함수의 활용

여러가지 고차함수를 사용하면 복잡한 문제도 쉽게 해결할 수 있습니다.

2차원 배열을 입력하여 입력받아 모든 숫자의 합를 리턴하는 경우

// 입출력 예시) [[1, 2, 3], [undefined, 5, '8']]  => 11
ffunction sumOfArraysInArray(arr) {
// 2차열 배열을 1차열 배열로 변환
  const newArr = arr.reduce(function(acc, cur) {
    return acc.concat(cur); // concat 함수를 이용하여 배열 합치기
  })
  const onlyNumArr = newArr.filter(function(el) {
  	return typeof el === 'number' // 배열의 요소를 숫자로 필터링
  })
  
  const result = onlyNumArr.reduce(function(acc, cur){
    return acc + cur;  // 배열 안의 요소의 총합 구하기
  }, 0)  // onlyNumArr가 빈배열일 경우 reduce 메소드를 호출할 수 없기 때문에 초기값 0을 넣어 0을 리턴
  return result;
}
profile
새로운 것을 기록하고 복습하는 공간입니다.

0개의 댓글