Higher Order Functions: Using Filter, Map and Reduce for More Maintainable Code - Lee-hyuna/33-js-concepts-kr GitHub Wiki
Filter
,Map
λ° Reduce
μ¬μ©
κ³ μ°¨ ν¨μ : μ μ§ λ³΄μκ° μ¬μ΄ μ½λλ₯Ό μν΄ μμ±μ Guido Schmitz
κ³ μ°¨ ν¨μλ μ½λλ₯Ό λ³΄λ€ μ μΈμ μΌλ‘ λ§λ€μ΄ μλ°μ€ν¬λ¦½νΈλ₯Ό κ°ννλ λ° λμμ΄ λ μ μμ΅λλ€. μ¦, μ§§κ³ κ°λ¨νκ² μ½μ μ μμ΅λλ€.
μ΄λ¬ν κΈ°λ₯μ μΈμ μ΄λ»κ² μ¬μ©νλμ§ μκ³ μλ κ²μ΄ μ€μν©λλ€. μ½λλ₯Ό μ΄ν΄νκ³ μ μ§νκΈ° μ½κ² λ§λλλ€.
λν κΈ°λ₯μ μλ‘ μ½κ² κ²°ν© ν μ μμ΅λλ€. μ΄κ²μ ꡬμ±(composition)μ΄λΌκ³ νλ©° μ¬κΈ°μλ μμΈν μ€λͺ
νμ§ μκ² μ΅λλ€. μ΄ κΈ°μ¬μμλ μλ°μ€ν¬λ¦½νΈμμ κ°μ₯ λ§μ΄ μ¬μ©λλ 3κ°μ§ κ³ μ°¨ ν¨μλ₯Ό λ€λ£° κ²μ
λλ€. μ΄λ€μ .filter()
, .map()
λ° .reduce()
μ
λλ€.
Filter
18μΈ μ΄μμΈ μ¬λλ€μ κ±Έλ¬λΈ 리μ€νΈ μ½λλ₯Ό μμ±νλ κ²μ μμν΄λ΄
μλ€.
μ°λ¦¬μ 리μ€νΈλ λ€μκ³Ό κ°μ΅λλ€.
const people = [
{ name: βJohn Doeβ, age: 16 },
{ name: βThomas Callsβ, age: 19 },
{ name: βLiam Smithβ, age: 20 },
{ name: βJessy Pinkmanβ, age: 18 }
];
18μΈ μ΄μμΈ μ¬λμ μ ννλ 1μ°¨ ν¨μμ μλ₯Ό μ΄ν΄ λ³΄κ² μ΅λλ€. ECMAScript νμ€ λλ ES6μ μΌλΆμΈ νμ΄ν ν¨μλ₯Ό μ¬μ©νμ¬ μ§§κ² μ°κ³ μμ΅λλ€. ν¨μλ₯Ό μ μνλ 짧μ λ°©λ²μΌ λΏμ΄λ―λ‘ κ΄νΈ, μ€κ΄νΈ λ° μΈλ―Έμ½λ‘ λΏλ§ μλλΌ function νμ΄ν λ° λ¦¬ν΄μ 건λλΈ μ μμ΅λλ€.
const peopleAbove18 = (collection) => {
const results = [];
for (let i = 0; i < collection.length; i++) {
const person = collection[i];
if (person.age >= 18) {
results.push(person);
}
}
return results;
};
μ΄μ 18μΈμμ 20μΈ μ¬μ΄μ λͺ¨λ μ¬λλ€μ μ ννλ €λ©΄ μ΄λ»κ²ν΄μΌν©λκΉ?
λ€λ₯Έ ν¨μλ₯Ό λ§λ€ μ μμ΅λλ€.
const peopleBetween18And20 = (collection) => {
const results = [];
for (let i = 0; i < collection.length; i++) {
const person = collection[i];
if (person.age >= 18 && person.age <= 20) {
results.push(person);
}
}
return results;
}
μ΄λ―Έ λ§μ λ°λ³΅ μ½λλ₯Ό μκ³ μμ κ² μ λλ€. λ³΄λ€ μΌλ°μ μΈ μ루μ μΌλ‘ μΆμν λ μ μμ΅λλ€. μ΄ λ ν¨μμλ 곡ν΅μ μ΄ μμ΅λλ€. κ·Έλ€μ 리μ€νΈλ₯Ό λ°λ³΅νκ³ μ£Όμ΄μ§ 쑰건μμ νν°λ§ν©λλ€.
"κ³ μ°¨ ν¨μλ νλ μ΄μμ ν¨μλ₯Ό μΈμλ‘ μ·¨νλ ν¨μμ λλ€." β Closurebridge
λ³΄λ€ μ μΈμ μ κ·Όλ°©μμΈ .filter()
λ₯Ό μ¬μ©νμ¬ μ΄μ ν¨μλ₯Ό κ°μ ν μ μμ΅λλ€.
const peopleAbove18 = (collection) => {
return collection.filter((person) => person.age >= 18);
}
κ·Έκ² λ€μ λλ€! μ΄ κ³ μ°¨ ν¨μλ₯Ό μ¬μ©νλ©΄ λ§μ μΆκ° μ½λλ₯Ό μ€μΌ μ μμ΅λλ€. λν μ½λλ₯Ό λ μ μ½μ μ μκ²ν©λλ€. νν°λ§λλ λ°©μμ μ€μνμ§ μμΌλ©° νν°λ§λ§ νλ©΄ λ©λλ€. μ΄ κ²μκΈ λ·λΆλΆμμ ν¨μλ₯Ό κ²°ν©νλ λ°©λ²μ λν΄ μ΄ν΄ λ³΄κ² μ΅λλ€.
Map
컀νΌλ₯Ό λ§μλ κ²μ μ’μνλμ§ μλ €μ£Όλ λμΌν μ¬λ 리μ€νΈμ μ΄λ¦μ λ°°μ΄μ λ΄ μλ€.
const coffeeLovers = [βJohn Doeβ, βLiam Smithβ, βJessy Pinkmanβ];
λͺ λ Ή λ°©μμ λ€μκ³Ό κ°μ΅λλ€:
const addCoffeeLoverValue = (collection) => {
const results = [];
for (let i = 0; i < collection.length; i++) {
const person = collection[i];
if (coffeeLovers.includes(person.name)) { person.coffeeLover = true;
} else {
person.coffeeLover = false;
}
results.push(person);
}
return results;
};
.map()
μ μ¬μ©νμ¬ λ μ μΈμ μΌλ‘ λ§λ€ μ μμ΅λλ€.
const incrementAge = (collection) => {
return collection.map((person) => {
person.coffeeLover = coffeeLovers.includes(person.name); return person;
});
};
.map()
μ κ³ μ°¨ ν¨μμ
λλ€. ν¨μκ° μΈμλ‘ μ λ¬ λ μ μμ΅λλ€.
Reduce
μΈμ , μ΄λ»κ² μ¬μ©νλμ§ μλ μ΄ ν¨μλ₯Ό λ§μμ λ€μ΄ ν κ²μ
λλ€.
.reduce()
μ λ©μ§ μ μ μ λλΆλΆμ ν¨μλ₯Ό μ¬μ©νμ¬ λ§λ€ μ μλ€λ κ²μ
λλ€.
λ¨Όμ κ°λ¨ν μλ₯Ό λ€μ΄ λ³΄κ² μ΅λλ€. μ°λ¦¬λ λͺ¨λ μ¬λλ€μ λμ΄λ₯Ό ν©μΉκ³ μΆμ΅λλ€. λ€μ ν λ² λͺ λ Ή λ°©μμ μ¬μ©νμ¬ μ΄ μμ μ μννλ λ°©λ²μ μ΄ν΄ λ³΄κ² μ΅λλ€. κΈ°λ³Έμ μΌλ‘ 컬λ μ (μμ§)μ λ°λ³΅νκ³ μ°λ Ήμ λ°λΌ λ³μλ₯Ό μ¦κ°μν΅λλ€.
const sumAge = (collection) => {
let num = 0;
collection.forEach((person) => {
num += person.age;
});
return num;
}
κ·Έλ¦¬κ³ .reduce()
λ₯Ό μ¬μ©νλ μ μΈμ μ κ·Ό λ°©μ.
const sumAge = (collection) => collection.reduce((sum, person) => { return sum + person.age;
}, 0);
μ°λ¦¬λ .reduce()
λ₯Ό μ¬μ©νμ¬ .map()
λ° .filter()
μ ꡬνμ λ§λ€ μλ μμ΅λλ€.
const map = (collection, fn) => {
return collection.reduce((acc, item) => {
return acc.concat(fn(item));
}, []);
}
const filter = (collection, fn) => {
return collection.reduce((acc, item) => {
if (fn(item)) {
return acc.concat(item);
}
return acc;
}, []);
}
μ²μμλ μ΄ν΄νκΈ° μ΄λ €μΈ μ μμ΅λλ€. κ·Έλ¬λ .reduce()
λ κΈ°λ³Έμ μΌλ‘ 컬λ μ
κ³Ό μ΄κΈ° κ°μ κ°μ§ λ³μλ‘ μμν©λλ€. κ·Έλ° λ€μ 컬λ μ
μ λ°λ³΅νκ³ κ°μ λ³μμ λ§λΆμ΄κ±°λ(λλ μΆκ°) ν©λλ€.
Combining map, filter and reduce
μ΄λ¬ν ν¨μκ° μ‘΄μ¬νλ€λ μ μ νλ₯ν©λλ€. κ·Έλ¬λ μ’μ μ μ μλ°μ€ν¬λ¦½νΈμ Array νλ‘ν νμ μ μ‘΄μ¬νλ€λ κ²μ λλ€. μ¦,μ΄ ν¨μλ€μ ν¨κ» μ¬μ©ν μ μμ΅λλ€! μ΄λ₯Ό ν΅ν΄ μ¬μ¬μ© κ°λ₯ν ν¨μλ₯Ό μ½κ² λ§λ€κ³ νΉμ ν¨μλ₯Ό μμ±νλ λ° νμν μ½λμ μμ μ€μΌ μ μμ΅λλ€.
κ·Έλμ μ°λ¦¬λ 18μΈ μ΄νμ μ¬λλ€μ κ±Έλ¬λ΄κΈ° μν΄ .filter()
λ₯Ό μ¬μ©νλ κ²μ λν΄ μ΄μΌκΈ°νμ΅λλ€. coffeeLover property
μ μΆκ°νλ .map()
κ³Ό reduce()
λ₯Ό ν©μ³μ λ§μΉ¨λ΄ λͺ¨λ μ¬λμ λμ΄λ₯Ό ν©ν ν©κ³λ₯Ό λ§λλλ€.
μ€μ λ‘ μ΄ μΈ λ¨κ³λ₯Ό κ²°ν©ν μ½λλ₯Ό μμ±ν΄ λ΄
μλ€.
const people = [
{ name: βJohn Doeβ, age: 16 },
{ name: βThomas Callsβ, age: 19 },
{ name: βLiam Smithβ, age: 20 },
{ name: βJessy Pinkmanβ, age: 18 }
];
const coffeeLovers = [βJohn Doeβ, βLiam Smithβ, βJessy Pinkmanβ];
const ageAbove18 = (person) => person.age >= 18;
const addCoffeeLoverProperty = (person) => {
person.coffeeLover = coffeeLovers.includes(person.name);
return person;
}
const ageReducer = (sum, person) => { return sum + person.age;}, 0);
const coffeeLoversAbove18 = people.filter(ageAbove18).map(addCoffeeLoverProperty);
const totalAgeOfCoffeeLoversAbove18 = coffeeLoversAbove18.reduce(ageReducer);
const totalAge = people.reduce(ageReducer);
λ§μΌ μ무μ μΈ λ°©μμΌλ‘ μννλ©΄ λ§μ λ°λ³΅ μ½λλ₯Ό μμ±νκ²λ©λλ€.
.map()
, .reduce()
, .filter()
λ‘ ν¨μλ₯Ό λ§λλ μ¬κ³ λ°©μμ
λΉμ μ΄ μΈ μ½λμ νμ§μ ν₯μμν¬ κ²μ
λλ€.
νμ§λ§ κ°λ
μ±λ λ§μ΄ λν©λλ€.
ν¨μ μμμ λ¬΄μ¨ μΌμ΄ μΌμ΄λκ³ μλμ§ μκ°ν νμλ μμ΅λλ€.
μ΄ν΄νκΈ° μ½μ΅λλ€.