/
๐Ÿ“™

JS Higher Order Function

JavaScript
Table of contents

.reduce()

js
Array.prototype.reduce<U>(callback: (state: U, element: T, index: number, array: T[]) => U, firstState?: U): U
  • ์›๋ณธ ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ด์ „์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜ ์‹คํ–‰ ๋ฐ˜ํ™˜๊ฐ’์„ ์ „๋‹ฌ ํ•˜์—ฌ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ดˆ๊ธฐ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ตœ์ดˆ๋กœ ์ „๋‹ฌ๋œ๋‹ค.
  • ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ํ•ฉ์‚ฐํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐ๊ฐ’์„ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.
    • ๋นˆ ๋ฐฐ์—ด์„ ํ˜ธ์ถœํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    • ์ดˆ๊ธฐ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ํšŒํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์–ธ์ œ๋‚˜ ์ดˆ๊ธฐ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ๋ณด๋‹ค ์•ˆ์ „ํ•˜๋‹ค.

reduce ์‘์šฉ

ํ‰๊ท  ๊ตฌํ•˜๊ธฐ(getMean)

๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ accumulator์™€ value๋ฅผ ๋”ํ•ด์„œ sum์„ ๋งŒ๋“ค๊ณ , ๋งˆ์ง€๋ง‰์— ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„๋Š” ๋กœ์ง

js
const data = [1, 2, 3, 4, 5, 6, 1];
const reducer = (accumulator, value, index, array) => {
if (index === array.length - 1) (accumulator + value) / array.length;
return accumulator + value;
};
const getMean = data.reduce(reducer, 0);
console.log(getMean); // 3.142857142857143

์ดˆ๊ธฐ๊ฐ’์„ 0์œผ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์•„๋„ ์ฒซ ๋ฒˆ์งธ ์ธ์ž์ธ data[0]๊ฐ€ accumulator๋กœ ๋„˜์–ด๊ฐ„๋‹ค.

ํ•˜์ง€๋งŒ ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•˜๋‹ค.

ํ‰ํƒ„ํ™”(flatten)

js
const data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const flatArrayReducer = (accumulator, value, index, array) => {
return [...accumulator, ...value];
};
const flattenedData = data.reduce(flatArrayReducer, []);
console.log(flattenedData); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

ํ‰ํƒ„ํ™” ๋งตํ•‘(flattenMap)

๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ๋ฐฐ์—ด์˜ ๊ฐ’์œผ๋กœ ๋“ค์–ด์žˆ๋Š” object ์˜ key ์กด์žฌ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ณ ,
unique ํ•œ โ€œcast ๋ฅผ key ๋กœ ๊ฐ–๋Š” ๋ฐฐ์—ด์˜ ๊ฐ’๋“คโ€์„ ์ตœ์ข…์ ์œผ๋กœ return ํ•˜๋Š” ๋กœ์ง

js
const input = [
{
"title": "์Šˆํผ๋งจ",
"year": "2005",
"cast": ["์žฅ๋™๊ฑด", "๊ถŒ์ƒ์šฐ", "์ด๋™์šฑ", "์ฐจ์Šน์›"]
},
{
"title": "์Šคํƒ€์›Œ์ฆˆ",
"year": "2013",
"cast": ["์ฐจ์Šน์›", "์‹ ํ•ด๊ท ", "์žฅ๋™๊ฑด", "๊น€์ˆ˜ํ˜„"]
},
{
"title": "๊ณ ์งˆ๋ผ",
"year": "1997",
"cast": []
}
];
const flatMapReducer = (accumulator, value, index, array) => {
const key = "cast";
if (value.hasOwnProperty(key) && Array.isArray(value[key])) {
value[key].forEach(val => {
if (accumulator.indexOf(val) === -1) {
accumulator.push(val);
}
});
}
return accumulator;
};
const flattenCastArray = input.reduce(flatMapReducer, []);
console.log(flattenCastArray); // ['์žฅ๋™๊ฑด', '๊ถŒ์ƒ์šฐ', '์ด๋™์šฑ', '์ฐจ์Šน์›', '์‹ ํ•ด๊ท ', '๊น€์ˆ˜ํ˜„']

reduce๋ฅผ map ์ฒ˜๋Ÿผ ์‚ฌ์šฉ

js
const arr = [1, 2, 3];
const mapReducer = (acc, value) => {
acc.push(value * 2);
return acc;
};
const result = arr.reduce(mapReducer, []);
const result2 = arr.reduce((acc, value) => {
acc.push(value * 2)
return acc;
}, []);
const result3 = arr.reduce((acc, value) => [...acc, value * 2], []);

reduce๋ฅผ filter ์ฒ˜๋Ÿผ ์‚ฌ์šฉ

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

reduce์™€ ๋‹ค๋ฅธ ๊ณ ์ฐจํ•จ์ˆ˜ ๋น„๊ต

reduce vs. map

js
const data = [1, 2, 3];
const initialValue = [];
const reducer = (accumulator, value) => {
accumulator.push(value * 2);
return accumulator;
};
const result = data.reduce(reducer, initialValue);
console.log(result); // [2, 4, 6]
const result2 = data.map(x => x * 2);
console.log(result2); // [2, 4, 6]

map์ด ๋” ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.

reduce vs. filter

js
const data = [1, 2, 3, 4, 5, 6];
const initialValue = [];
const reducer = (accumulator, value) => {
if (value % 2 != 0) {
accumulator.push(value);
}
return accumulator;
};
const result1 = data.reduce(reducer, initialValue);
console.log(result1); // [1, 3, 5]
const result2 = data.filter(x => x % 2 != 0);
console.log(result2); // [1, 3, 5]

filter๊ฐ€ ๋” ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.

reduce vs. filter+map

js
const data = [1, 2, 3, 4, 5, 6];
const initialValue = [];
const reducer = (accumulator, value) => {
if (value % 2 != 0) {
accumulator.push(value * 2);
}
return accumulator;
}
const result1 = data.reduce(reducer, initialValue);
console.log(result1); // [2, 6, 10]
const result2 = data.filter(x => x % 2 != 0).map(x => x * 2);
console.log(result2); // [2, 6, 10]

filter/map์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๋ฐฐ์—ด์„ ๋‘ ๋ฒˆ ์ˆœํšŒํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ reduce๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ฐฐ์—ด์„ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒํ•˜๋ฉด ๋œ๋‹ค.

reducer๋ผ๋Š” ํ•จ์ˆ˜๋กœ ๋กœ์ง์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด ์ˆœํšŒ๋ฅผ ์ ๊ฒŒํ•ด ๋น„์šฉ์ด ์ ๊ฒŒ๋“ ๋‹ค. ํ•˜์ง€๋งŒ filter/map์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ๋” ์ง๊ด€์ ์ด๋‹ค.

  • filter/map
    • ๋ฐฐ์—ด์„ ๋‘ ๋ฒˆ ์ˆœํšŒ
    • ์–ด๋–ค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ๋” ์ง๊ด€์ 
  • reducer
    • ๋ฐฐ์—ด์„ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒ
    • ์žฌ์‚ฌ์šฉ์„ฑ

.filter()

๋ฐฐ์—ด์—์„œ ํŠน์ • ์ผ€์ด์Šค๋งŒ ํ•„ํ„ฐ๋ง ์กฐ๊ฑด์œผ๋กœ ์ถ”์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

js
Array.prototype.filter(callback: (value: T, index: number, array: Array) => any, thisArg?: any): T[]
  • ์›๋ณธ ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • filter ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด if ๋ฌธ์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ true์ธ ๋ฐฐ์—ด ์š”์†Œ์˜ ๊ฐ’๋งŒ์„ ์ถ”์ถœํ•œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

.map()

map ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉฐ ์š”์†Œ ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋งตํ•‘ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.

js
Array.prototype.map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]
  • ์›๋ณธ ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’(๊ฒฐ๊ณผ๊ฐ’)์œผ๋กœ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ this๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ๋ฐฐ์—ด ์š”์†Œ์˜ ๊ฐ’, ์š”์†Œ ์ธ๋ฑ์Šค, map ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๋ฐฐ์—ด
    • 2๋ฒˆ์งธ ์ธ์ž this๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉด this === window
    • ES6์˜ Arrow function๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด this๋ฅผ ์ƒ๋žตํ•˜์—ฌ๋„ ๋™์ผํ•œ ๋™์ž‘์„ ํ•œ๋‹ค.

.forEach()

forEach ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉฐ ์š”์†Œ ๊ฐ’์„ ์ฐธ์กฐํ•˜์—ฌ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.

js
Array.prototype.forEach(callback: (value: T, index: number, array: T[]) => void, thisArg?: any): void
  • ์›๋ณธ ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • forEach ๋ฉ”์†Œ๋“œ๋Š” ์›๋ณธ ๋ฐฐ์—ด(this)์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉฐ ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ์— ๋Œ€ํ•˜์—ฌ ์ธ์ž๋กœ ์ฃผ์–ด์ง„ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
    ๋ฐ˜ํ™˜๊ฐ’์€ undefined์ด๋‹ค.
  • ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ค‘๊ฐ„์— ์ˆœํšŒ๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์—†๋‹ค.
  • for ๋ฌธ์— ๋น„ํ•ด ์„ฑ๋Šฅ์ด ์ข‹์ง€๋Š” ์•Š์ง€๋งŒ for ๋ฌธ๋ณด๋‹ค ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.
  • ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ this๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋ฐฐ์—ด ์š”์†Œ์˜ ๊ฐ’, ์š”์†Œ ์ธ๋ฑ์Šค, filter ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๋ฐฐ์—ด

Reference

medium.com/@hongkev...79857ece

opentogether.tistory.com/7...7

logo
Things I've Learned