고차함수란?
함수를 인자(argument)로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수
함수는 변수에 저장 가능.
그 변수를 인자로 받을 수도 있다.
function square(num) {
return num * num;
}
function add5(num) {
return num + 5;
}
function mul3(num) {
return num * 3;
}
function isOdd(num) {
return num % 2 !== 0;
}
let output = pipe(add5, square);
console.log(output(4)); // --> 81
output = pipe(square, add5, mul3);
console.log(output(4)); // --> 63
output = pipe(square, mul3, add5, add5, isOdd);
console.log(output(4)); // --> false
function pipe(...funcN) {
// TODO: 여기에 코드를 작성합니다.
return function(num) { /// 새로운 함수를 리턴한다
let result = num // result라는 변수는 위 함수의 num 인자다
for(let i=0; i<funcN.length; i++) { // i=0 부터 함수의 길이만큼 루프를 돌린다
result = funcN[i](result) // 초기 result의 값은 func[0]번째에 들어가서 result값은 다시 정의된다
}
return result
}
}
function isOdd(num) {
return num % 2 === 1;
}
function isEven(num) {
return !isOdd(num);
}
let output = filterCallback(isOdd, [1, 2, 3, 4]);
console.log(output); // --> [1, 3]
output = filterCallback(isEven, [1, 2, 3, 4]);
console.log(output); // --> [2, 4]
function filterCallback(func, arr) {
// TODO: 여기에 코드를 작성합니다.
let result =[]
for(let el of arr){ // arr의 각 인자를 순회하며
if(func(el)) { // 받아온 func에 인자를 대입하여 조건이 참이라면
result.push(el) // 빈 배열 result에 해당 요소를 푸쉬한다
}
}return result
}
// for ...in은 객체(Object)의 key를 순회하고, for ...of는 iterable객체의 value를 순회한다
// else { return []} 은 오류 >> arr[i]번째 el이 부합하지 않을경우 공백을 리턴하면 그상태에서 함수가 종료되기 때문
const obj = {
key: [1000, 20, 50, 500],
};
let output = getElementsLessThan100AtProperty(obj, 'key');
console.log(output); // --> [20, 50]
function lessThan100(number) {
return number < 100; // 100보다 작은 숫자를 리턴
}
function getElementsLessThan100AtProperty(obj, property) {
// TODO: 여기에 코드를 작성합니다.
let val = obj[property] // 객체의 속성값을 val이라 선언
if(Array.isArray(val)) { // 속성값 val이 배열이라면
return val.filter(function(el){
return typeof el === 'number' && lessThan100(el)
}) // number형이면서 100보다 작은 숫자들만 필터링하여 리턴
}
return []
}
// ** 속성값에 접근하는 메소드는 obj.property, obj[property] 두가지 있음
let output = getOnlyAllowedToDrink([
{ name: 'Harry', age: 15 },
{ name: 'Ron', age: 14 },
{ name: 'Hermione', age: 14 },
]);
console.log(output); // --> []
output = getOnlyAllowedToDrink([
{ name: 'Cho', age: 14 },
{ name: 'Dumbledore', age: 87 },
{ name: 'Snape', age: 53 },
{ name: 'Hagrid', age: 43 },
]);
console.log(output); // --> ['Dumbledore', 'Snape', 'Hargrid']
output = getOnlyAllowedToDrink([]);
console.log(output); // --> []
function getOnlyAllowedToDrink(arr) {
// TODO: 여기에 코드를 작성합니다.
const A = arr.filter(function(el){ // age가 18살 이상인 객체들만 필터링
return el.age >= 18
})
return A.map(function(el){ // 필터링된 데이터에서 이름 추출
return el.name
})
}
let output = computeAverageOfNumbers([4, 5, 6]);
console.log(output); // --> 5
function computeAverageOfNumbers(arr) {
// TODO: 여기에 코드를 작성합니다.
if(arr.length === 0){ // 빈배열이면 0 리턴
return 0
}
else { // 아니면 누적 메서드 reduce 사용해서 배열을 모두 더한다
let total = arr.reduce(function(acc, val){
return acc + val
})
return total/arr.length // 누적 점수/전체 길이
}
}
const records = [
{
score: 63,
animal: 'dog',
},
{
score: 75,
animal: 'dog',
},
{
score: 87,
animal: 'cat',
},
{
score: 98,
animal: 'cat',
},
{
score: 24,
animal: 'dog',
},
];
let output = calculateScore(records, 'cat');
console.log(output); // --> 185
output = calculateScore(records, 'dog');
console.log(output); // --> 162
output = calculateScore([], 'dog');
console.log(output); // --> 0
output = calculateScore(records, 'mouse');
console.log(output); // --> 0
function calculateScore(records, value) {
const sum=records.reduce(function(acc, cur){ // record의 객체들을 누적해서 더할건데
if(cur.animal === value){ // 현재 읽어들이는 동물 이름과 입력된 동물 이름과 매칭될 때만 누적한다
return acc + cur.score
}
else{ // 매칭되지 않으면 더하지 않고 누적값을 리턴
return acc
}
}, 0) // 초기값은 0
return sum
}
let output = getLengthOfLongestElement(['one', 'two', 'three']);
console.log(output); // --> 5
function getLengthOfLongestElement(arr) {
// TODO: 여기에 코드를 작성합니다.
if(arr.length === 0){ // 반배열이면 0 리턴
return 0
}
return arr.reduce(function(acc, cur){ // 아니면 순회하며 비교
if(acc.length>=cur.length) { // 누적값이 현재값 이상이면
return acc // 그대로 둔다
}
else{
return cur // 반대면 현재값을 리턴한다
}
}).length // 마지막에 추출되는 인자의 길이를 리턴
} // ** return acc.length, return cur.length하면 비교 대상이 문자가 아니라 숫자로 바뀌어서 값이 이상해짐
let studentList = [
{
name: 'Anna',
gender: 'female',
grades: [4.5, 3.5, 4],
},
{
name: 'Dennis',
gender: 'male',
country: 'Germany',
grades: [5, 1.5, 4],
},
{
name: 'Martha',
gender: 'female',
grades: [5, 4, 4, 3],
},
{
name: 'Brock',
gender: 'male',
grades: [4, 3, 2],
},
];
let output = studentReports(studentList);
console.log(output); // -->
[
{ name: 'Anna', gender: 'female', grades: 4 },
{ name: 'Martha', gender: 'female', grades: 4 },
];
function studentReports(students) {
// TODO: 여기에 코드를 작성합니다.
const filter=students.filter(function(el){
return el.gender === 'female' // 여성인 학생들만 필터링
})
return filter.map(function(el){ // 필터링한 데이터를 변경할건데
const sum=el.grades.reduce(function(acc,cur){ // 여학우들의 점수를 누산하여
return acc+cur
})
const avg= sum/el.grades.length // 평균을 구한다
el.grades=avg // 점수값을 평균값으로 변경하고
return el // 바뀐 객체를 리턴한다
})
}
let output = sumOfArraysInArray([
[1, 2],
[undefined, 4, '5'],
[9, 'hello'],
]);
console.log(output); // --> 16
function sumOfArraysInArray(arr) {
// TODO: 여기에 코드를 작성합니다.
const horizon = arr.reduce(function(acc,cur){ // 받아온 배열을 변경할건데
return acc.concat(cur) // 현재값을 누적값에 이어붙이는 형식으로 변경. 즉 수직 정렬된 데이터를 수평정렬 시킨다
})
const filter = horizon.filter(function(el){ // 변경된 데이터에서 숫자형만 필터링
return typeof el === 'number'
})
return filter.reduce(function(acc,cur){ // 필터링된 데이터를 누산하고 리턴
return acc + cur
}, 0) // 초기값 0
}