[219316] TIL
오늘 배운 것
수도코드 작성하기, 고차함수(filter, map, reduce)
수도코드 pseudocode
수도코드 작성하기, 고차함수(filter, map, reduce)
수도코드란 알고리즘을 일반적인 언어로 바꾸어 쓰는 것을 말한다.문제를 어떻게 해결해 나갈지 밑그림을 그리는 작업이라고 할 수 있다. 사실 수도코드를 작성할 수 없다면, 문제를 풀 수 없는 것이 당연하다. 그런데도 문제를 보자마자 수도코딩을 작성하려고 하기 보다는, 머리로 어떻게든 이해해서 코딩을 시작하는 버릇이 있다. 간단한 알고리즘으로 풀 수 있는 문제라면 이런 방법이 통하겠지만, 알고리즘이 점점 복잡해지면서 이런 습관이 얼마나 나의 발전을 가로 막는지 피부로 와 닿는다. 사실 수도코딩을 작성할 수 없다면 문제를 풀 수 없는 것은 당연하다. 문제를 이해하지 못하거나, 문제를 해결하는데 필요한 메소드들을 알지 못하기 때문에 수도코드도 작성할 수 없는 것이다.
function replaceFoo(text) {
// foo라는 글자의 index가 -1이 아니면 단어를 찾은 것이다
while( text.indexOf('foo') !== -1 ) { // index를 발견하면
let index = text.indexOf('foo');
// index를 이용해 foo 바로 앞까지의 텍스트를 얻어내고
let beforeText = text.slice(0, index);
// foo 대신 새로운 단어를 넣는다
let replaceText = 'BAR';
// foo 이후의 텍스트를 넣는다
let afterText = text.slice(index + 3); // 'foo'는 세 글자이므로 3을 더함
text = beforeText + replaceText + afterText;
}
return text; // 바뀐 내용을 리턴한다
}
이렇게 내가 어떤 과정으로 문제를 풀어 나갈지 수도코드로 적어보는 습관을 반드시 갖자. 헬프 데스크에 올라오는 질문에는 어김없이 수도코드를 작성해보라는 답변이 달린다. 이제 뒤에 나올 고차함수와 알고리즘 문제들을 해결하기 위해서는 내 머리와 직관에만 의존해서는 결코 안된다. 아니, 머리와 직관을 믿으면 안된다.
고차함수
자바스크립트에서 함수는 일급 객체(first-class citizen) 대우를 받는다. 일급 객체로써의 특징은 다음과 같다.
- 변수에 할당(assignment)할 수 있다.
- 다른 함수의 인자(argument)로 전달될 수 있다.
- 다른 함수의 결과로서 리턴될 수 있다.
함수가 변수에 할당되는 건 이미 익숙하다.
함수표현식
// 아래는 변수 square에 함수를 할당하는 함수 표현식입니다.
// 자바스크립트에서 함수는 일급 객체이기 때문에 변수에 저장할 수 있습니다.
// 함수 표현식은 할당 전에 사용할 수 없습니다.
// square(7); // --> ReferenceError: Can't find variable: square
const square = function (num) {
return num * num;
};
// square에는 함수가 저장되어 있으므로 (일급 객체), 함수 호출 연산자 '()'를 사용할 수 있습니다.
output = square(7);
console.log(output); // --> 49
** 함수 표현식은 함수 선언식과 다르게 호이스팅이 적용되지 않는다.
나머지 두 가지 특징이 고차함수의 특징이라고 말할 수 있다. 따라서 고차 함수(higher order function)는 함수를 인자(argument)로 받거나 함수를 리턴하는 함수를 말한다. 이 때 다른 함수(caller)의 인자(argument)로 전달되는 함수는 콜백 함수(callback function)라고 한다.
다른 함수를 인자로 받는 경우
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
함수를 리턴하는 경우
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
함수를 인자로 받고, 함수를 리턴하는 경우
function double(num) {
return num * 2;
}
function doubleAdder(added, func) {
const doubled = func(added);
return function (num) {
return num + doubled;
};
}
// 함수 doubleAdder는 고차 함수입니다.
// 함수 doubleAdder의 인자 func는 함수 doubleAdder의 콜백 함수 입니다.
// 함수 double은 함수 doubleAdder의 콜백으로 전달되었습니다.
// doubleAdder(5, double)는 함수이므로 함수 호출 기호 '()'를 사용할 수 있습니다.
doubleAdder(5, double)(3); // -> 13
// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있습니다. (일급 객체)
const addTwice3 = doubleAdder(3, double);
addTwice3(2); // --> 8
대표적인 내장 고차함수 (filter, map, reduce)
const data = [
{
gender: 'male',
age: 24,
},
{
gender: 'male',
age: 25,
},
{
gender: 'female',
age: 27,
},
{
gender: 'female',
age: 22,
},
{
gender: 'male',
age: 29,
},
];
function getAverageAgeOfMaleAtOnce(data) {
const onlyMales = data.filter(function (d) {
// data.filter는 배열의 각 요소에 인자로 전달 받은 함수를 적용하고,
// 그 결과가 true인 요소만을 갖는 배열을 리턴합니다.
return d.gender === 'male';
});
const numOfMales = onlyMales.length;
const onlyMaleAges = onlyMales.map(function (d) {
// onlyMales.map는 배열의 각 요소에 인자로 전달 받은 함수를 적용하고,
// 각 결과를 요소로 갖는 배열을 리턴합니다.
return d.age;
});
const sumOfAges = onlyMaleAges.reduce(function (acc, cur) {
// onlyMaleAges.reduce는 배열의 각 요소에 인자로 전달 받은 함수를 적용하고,
// 각 결과를 두 번째 인자로 전달 받은 초기값(0)에 누적한 결과를 리턴합니다.
return acc + cur;
}, 0);
return sumOfAges / numOfMales;
}
Author And Source
이 문제에 관하여([219316] TIL), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kwd8905/219316-TIL저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)