DAY 018. 코드스테이츠 4주차 - JS (고차 함수)

슈레더·2021년 7월 7일

코드스테이츠

목록 보기
18/25
post-thumbnail

고차함수가 전혀 이해되지 않는다. 블로그로 정리한 내용을 작성하고 싶은데 이해가 되지 않아
어떻게 정리해야할 지 모르겠다. 그나마 페어 님과 같이 진행할 땐 좀 수월했는데 페어가 끝나고
다시 혼자 뭘 하려하니 꽉 막힌 기분이 들었다. 한마디로 멘붕...
함수를 인자로 받고 함수를 리턴하고 이런 게 다중으로 들어가니까 정신을 못차리겠다.
전혀 익숙해지지 않는 개념이다. 이거 완벽히 이해하려면 오랜 시간이 걸릴 것 같다.

일급 객체(First-class citizen)

자바스크립트에는 특별한 대우를 받는 일급 객체(first-class citizen)가 있다. 대표적인 일급 객체 중 하나가 함수이다. (자바스크립트가 나온 시점을 고려했을 때,) 자바스크립트에서 함수는 아래와 같이 특별하게 취급된다.

  • 변수에 할당(assignment) 할 수 있다.
  • 다른 함수의 인자(argument)로 전달될 수 있다.
  • 다른 함수의 결과로서 리턴될 수 있다.

콜백 함수(Callback function)

콜백 함수(Callback function)는 고차 함수에서 함수 자체를 리턴할 때 다른 함수(caller)의 인자(argument)로 전달되는 함수이다.

고차 함수(Higher order function)

고차 함수(higher order function)는 함수를 인자(argument)로 받을 수 있는 함수이다.

function double(num) {
  return num * 2;
}

function doubleNum(func, num) {
  return func(num);
}

/*
 * 함수 doubleNum은 다른 함수를 인자로 받는 고차 함수입니다.
 * 함수 doubleNum의 첫 번째 인자 func에 함수가 들어올 경우
 * 함수 func는 함수 doubleNum의 콜백 함수입니다.
 * 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수입니다.
 */
let output = doubleNum(double, 4);
console.log(output); // -> 8

커링 함수(Currying function)

커링 함수(Currying function)는 함수를 리턴하는 함수이다.

function adder(added) {
  return function (num) {
    return num + added;
  };
}

/*
 * 함수 adder는 다른 함수를 리턴하는 고차 함수입니다.
 * adder는 인자 한 개를 입력받아서 함수(익명 함수)를 리턴합니다.
 * 리턴되는 익명 함수는 인자 한 개를 받아서 added와 더한 값을 리턴합니다.
 */

// adder(5)는 함수이므로 함수 호출 연산자 '()'를 사용할 수 있습니다.
let output = adder(5)(3); // -> 8
console.log(output); // -> 8

// adder가 리턴하는 함수를 변수에 저장할 수 있습니다.
// javascript에서 함수는 일급 객체이기 때문입니다.
const add3 = adder(3);
output = add3(2);
console.log(output); // -> 5

내장 고차 함수

map

  • 배열의 각 요소가
  • 특정 논리(함수)에 의해
  • 다른 요소로 지정(map) 되는 것

filter

  • 배열의 각 요소가
  • 특정 논리(함수)에 따르면, 사실(boolean)일 때
  • 따로 분류하는 것(filter)

reduce

  • 배열의 각 요소를
  • 특정 방법(함수)에 따라
  • 원하는 하나의 형태로
  • 응축하는 것(reduction)

map, filter, reduce 사용법

일반적인 Loop 구문

// for
var arr = [3, 9, 4, 2, 7, 6]
var new_arr = []

for (var i = 0; i < arr.length; i++) {
    if (arr[i] % 2 === 0) {     // 2의 배수
        new_arr.push(arr[i])
    }
}
console.log(new_arr)	// 4, 2, 6
// forEach()
var arr = [3, 9, 4, 2, 7, 6]
var new_arr = []
arr.forEach(function (n) {
    if (n % 2 ===0) {
        new_arr.push(n)
    }
})
console.log(new_arr)	// 4, 2, 6
// forEach with arrow fuction
var arr = [3, 9, 4, 2, 7, 6]
var new_arr = []
arr.forEach( (n) => { if (n % 2 === 0) new_arr.push(n) })
console.log(new_arr)	// 4, 2, 6

map

map()
인자값: currenValue, index, array
요소를 일괄적으로 변경

var arr = ['foo', 'hello', 'diamond', 'A']
// 각 요소의 글자 길이값 반환
var arr2 = arr.map((v) => v.length)
console.log(arr2)	 // [3, 5, 7, 1]

filter

filter()
요소를 걸러내어 배열로 true/false 반환, 없으면 빈 배열

var arr = [4, 15, 377, 395, 400, 1024, 3000]
var arr2 = arr.filter((v) => (v % 5 === 0))
console.log(arr2)	// [15, 395, 400, 3000]

find

find()
단 하나의 요소만 반환, 여러 개 있으면 처음값만 반환

let arr = [4, 15, 377, 395, 400, 1024, 3000]
let arr2 = arr.find((n) => (n % 5 === 0))
console.log(arr2)	// 15

reduce

reduce()
인자값은 callback [, initivalValue]
callback은 previouseValue, currentValue, currentIndex, array
[, initivalValue]는 옵션
reduce()는 위의 map, find, filter 대체 가능

let arr = [9, 2, 8, 5, 7]
let sum = arr.reduce((pre, val) => pre + val)
console.log(sum)	// 31

// map
var arr = ['foo', 'hello', 'diamond', 'A']
var arr2 = arr.reduce((pre, value) => {
    pre.push(value.length)
    return pre
}, [])
console.log(arr2)   // [3, 5, 7, 1]

// filter
var arr = [4, 15, 377, 395, 400, 1024, 3000]
var arr2 = arr.reduce((pre, value) => {
    if (value % 5 == 0) {
        pre.push(value);
    }
    return pre;
}, []);
console.log(arr2)    // [15, 395, 400, 3000]

// find
var arr = [4, 15, 377, 395, 400, 1024, 3000]
var arr2 = arr.reduce((pre, value) => {
    if (typeof pre == 'undefined' && value % 5 == 0) {
        pre = value;
    }
    return pre;
}, undefined);
console.log(arr2)  // 15

출처 https://velog.io/@decody/map-%EC%A0%95%EB%A6%AC

profile
shreder0804

0개의 댓글