javascript functional programming map filter and reduce - Lee-hyuna/33-js-concepts-kr GitHub Wiki

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ โ€” map, filter ๊ทธ๋ฆฌ๊ณ  reduce

์›๋ฌธ: JavaScript Functional Programming โ€” map, filter and reduce

์—ฌ๋Ÿฌ๋ถ„์ด ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๋”๋ผ๋„, ์•„๋งˆ๋„ map, filter, ๊ทธ๋ฆฌ๊ณ  reduce๋ฅผ ์‚ฌ์šฉํ•ด ๋ดค์„ ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ๋“ค์€ ๋งค์šฐ ์œ ์šฉํ•˜๊ณ  ๋” ๊นจ๋—ํ•œ ๋กœ์ง์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด ๊ธฐ์‚ฌ์˜ ์ œ๋ชฉ์€ '์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ'์ด์ง€๋งŒ, ๊ทธ ์ฃผ์ œ์— ๋„ˆ๋ฌด ๊นŠ์ด ๋น ์ ธ๋“ค์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ์šฐ๋ฆฌ๋Š” map, filter ๊ทธ๋ฆฌ๊ณ  reduce๋ฅผ ์‚ดํŽด ๋ณผ ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•จ์ˆ˜ํ˜•์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ์ฝ”๋”ฉ์˜ ์ •๋ง ๋ฉ‹์ง„ ์„ธ๊ณ„์— ๋Œ€ํ•œ ์ธ์‹์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ๋งˆ์ผ€ํŒ… ์ˆ˜๋ฒ•์ด๋‹ค. ์•„๋งˆ ๋“ค์–ด๋ณธ ์ ๋„ ์—†์„ ๊ฒƒ์ด๊ณ , ๋“ค์€ ์ ๋„ ์—†์„ ๊ฒƒ์ด์ง€๋งŒ, ์ƒ๊ฐํ•ด ๋ณธ ์ ๋„ ์—†์„ ๊ฒƒ์ด๋‹ค.

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Frisby ๊ต์ˆ˜์˜ ๊ฐ€์žฅ ์ ์ ˆํ•œ ๊ธฐ๋Šฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋ผ. (Link) ๋˜๋Š” Functional-Light JavaScript by the awesome Kyle Simpson (Link) ๋˜๋Š” ์ „์„ค์ธ ๋‚จ์ž, ์—๋ฆญ ์—˜๋ฆฌ์—‡์˜ ๊ธ€์„ ๋ณด๋ผ. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด ์ž์ฃผ ์ด์•ผ๊ธฐํ•œ๋‹ค.

์ด ๊ฐœ๋…๋“ค ์ค‘ ์ผ๋ถ€๊ฐ€ ์ฒ˜์Œ ์ ‘ํ–ˆ์„ ๋•Œ ์ดํ•ด๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ด๋„, ๊ฑฑ์ •ํ•˜์ง€ ๋ง์•„๋ผ. ๊ทธ๊ฒƒ์€ ๋‹น์—ฐํ•œ ๊ฒƒ์ด๋‹ค. ๊ณ„์†ํ•˜๋ฉด ๊ณง ๊ทธ ๋ณด์ƒ์„ ์–ป๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ๋‚ด ์ƒ๊ฐ์— ์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋‹น์‹ ์ด ๋” ๋‚˜์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์“ฐ๋Š” ๋ฐ ๋„์›€์ด ๋  ์ƒˆ๋กœ์šด ์ ‘๊ทผ๋ฒ•์„ ์†Œ๊ฐœํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

map

MDN์ด ๋งํ•˜๋Š” 'map'์ด ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณด์ž (Link):

์„ค๋ช…

map() ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์š”์†Œ์— ์ œ๊ณต๋œ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜์—ฌ, ๊ฒฐ๊ณผ๋กœ ์ƒˆ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ๋‹ค.

์˜ˆ์ œ

const numbers = [2, 4, 8, 10];  
const halves = numbers.map(x => x / 2);// halves is [1, 2, 4, 5]

ํŠน๋ณ„ํ•  ๊ฒƒ์ด ์—†๋‹ค. ๋‹จ์ง€ numbers ๋ฐฐ์—ด์˜ ๊ฐ’์„ ๊ฒ€ํ† ํ•˜์—ฌ, ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋กœ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด (halves)์„ ๋งŒ๋“ค์—ˆ๋‹ค.

map์€ ๋ฐฐ์—ด์ด ์กด์žฌํ•˜๊ณ , ๊ทธ ๋ฐฐ์—ด์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

filter

MDN์ด ๋งํ•˜๋Š” 'filter'๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณด์ž (Link):

์„ค๋ช…

filter() ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์š”์†Œ์— ์ œ๊ณต๋œ ํ•จ์ˆ˜์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํŒ๋‹จํ•˜์—ฌ, ๊ฒฐ๊ณผ๋กœ ์ƒˆ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ๋‹ค.

์˜ˆ์ œ

const words = ["spray", "limit", "elite", "exuberant", "destruction", "present"];  
  
const longWords = words.filter(word => word.length > 6);// longWords is ["exuberant", "destruction", "present"]

map๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ filter ์—ญ์‹œ ํŠน๋ณ„ํ• ๊ฒŒ ์—†๋‹ค. words ๋ฐฐ์—ด์—์„œ ์–ด๋–ค ๊ฐ’์ด ์กฐ๊ฑด์— ๋งž๋Š”์ง€ ํ™•์ธํ•˜์—ฌ (๊ธธ์ด๊ฐ€ 6 ์ด์ƒ), ํ•ด๋‹น ๊ฐ’๋“ค์„ ์ƒˆ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

reduce

reduce๋Š” ๋‹ค์žฌ๋‹ค๋Šฅํ•˜๊ณ  ์œ ์—ฐํ•˜๋‹ค. ์ˆ˜ ๋งŽ์€ ์‹œ๋‚˜๋ฆฌ์˜ค์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€์ฒด๋กœ ์ˆซ์ž ๋ฐฐ์—ด์˜ ํ•ฉ์„ ๊ตฌํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์†์„ฑ์— ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์— ์‚ฌ์šฉ๋˜๋Š”๋ฐ, ์•ˆํƒ€๊นŒ์šด ์ผ์ด๋‹ค.

MDN์ด ๋งํ•˜๋Š” 'reduce'๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณด์ž (Link):

์„ค๋ช…

reduce() ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ(์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ)์— ๋Œ€ํ•ด ๋ˆ„์‚ฐ๊ธฐ(accumulator)์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜์—ฌ ๋‹จ์ผ ๊ฐ’์œผ๋กœ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.

์˜ˆ์ œ

const total = [0, 1, 2, 3].reduce((acc, value) => acc + value, 1);// total is 7

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์˜ˆ์‹œ๋Š” ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ž๋“ค๋กœ ๋ถ€ํ„ฐ ์•Œ์•„์ฐจ๋ฆฐ ๊ฒƒ์€ ์–ด๋–ค ์ˆซ์ž๋“ค์„ ํ•ฉํ•  ์ผ์ด ๋ณ„๋กœ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ reduce๊ฐ€ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜ ํ˜น์€ ์–ด๋–ค ์ˆซ์ž๋“ค์„ ํ•ฉํ•ด์•ผ ํ•  ๋•Œ์—๋งŒ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์ง€๋งŒ (์•ž์—์„œ ์•”์‹œํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ) reduce๋Š” ๋‹จ์ˆœํžˆ ํ•ฉํ•œ ๊ฒƒ ์ด์ƒ์˜ ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

reduce์˜ ์ •๋ง ๋ฉ‹์ง„ ์ ์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ๋กœ ์ „๋‹ฌํ•˜์—ฌ ์†์ž„์ˆ˜ ๊ฐ™์ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

Compose Functions (ํ•จ์ˆ˜์˜ ํ•ฉ์„ฑ)

reduce๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ํ•ฉ์„ฑํ•˜๋Š” ์˜ˆ์ œ๋Š” Eric Elliott์ด ์“ด reduce ๊ธ€์—์„œ ๋ฐœ์ทŒํ•˜์˜€๋‹ค. Eric Elliott์€ ํ•ญ์ƒ ์–‘์งˆ์˜ ์ปจํ…์ธ ๋ฅผ ์ƒ์‚ฐํ•˜๊ณ  ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ๊ทธ๋ฅผ ๋”ฐ๋ž์œผ๋ฉด ์ข‹๊ฒ ๋‹ค. Link

์šฐ๋ฆฌ์—๊ฒŒ ๊ฐ€์žฅ ํฅ๋ฏธ๋กœ์šด ๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
/*
const compose = (...fns) => {
	return (x) => {
		return fns.reduceRight((v, f) => f(v), x)
	}
};
*/

๋งˆ์น˜ ์‹œ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๋Š”๊ฐ€?

compose๋Š” ์ปค๋ง ํŒจํ„ด ํ˜•ํƒœ๋กœ์จ ๋ถ€๋ถ„์ ์œผ๋กœ ์ ์šฉ๋˜๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์Œ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•œ๋‹ค. rest parameters ๊ฐ€ ์‚ฌ์šฉ๋œ ๊ฒƒ์„ ์ฃผ๋ชฉํ•˜๋ผ. ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๋งŒํผ์˜ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌ ํ•˜์—ฌ fns ๋ฐฐ์—ด์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฐ compose์— ํ•จ์ˆ˜๋“ค์„ ์ „๋‹ฌํ•œ ๋‹ค์Œ ์ดˆ๊ธฐ ๊ฐ’ (x)๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

์ˆ˜์ง‘๋œ ํ•จ์ˆ˜์˜ ๋ฐฐ์—ด(fns)์— x๋ฅผ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ reduceRight๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

reduceRight๋Š” reduce์™€ ๊ธฐ๋Šฅ์€ ๊ฐ™์ง€๋งŒ ๋ฐฐ์—ด์˜ ๋์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์‹œ์ž‘์ ์œผ๋กœ ์ด๋™ํ•œ๋‹ค.

์‚ฌ์šฉ ์˜ˆ:

const add1 = n => n + 1;  
const double = n => n * 2;const add1ThenDouble = compose(  
  double,  
  add1  
);add1ThenDouble(2); // 6  
// ((2 + 1 = 3) * 2 = 6)

ํ›Œ๋ฅญํ•˜๋‹ค!

ํ”„๋กœ๋ฏธ์Šค ์ฒด์ด๋‹

reduce๋ฅผ ์ด์šฉํ•œ ํ”„๋กœ๋ฏธ์Šค ์ฒด์ธ ์˜ˆ์ œ๋Š” Bobby Brennan์˜ ํ”„๋กœ๋ฏธ์Šค ํŒจํ„ด๊ณผ ์•ˆํ‹ฐ-ํŒจํ„ด์— ๊ด€ํ•œ ํ›Œ๋ฅญํ•œ ๊ธ€์—์„œ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„ :

let itemIDs = [1, 2, 3, 4, 5];
itemIDs.reduce((promise, itemID) => {  
  return promise.then(_ => api.deleteItem(itemID));  
}, Promise.resolve());

์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด์„๋œ๋‹ค :

Promise.resolve()  
.then(_ => api.deleteItem(1))  
.then(_ => api.deleteItem(2))  
.then(_ => api.deleteItem(3))  
.then(_ => api.deleteItem(4))  
.then(_ => api.deleteItem(5));

์ด ์˜ˆ์ œ๋Š” ๋ณต์žกํ•˜์ง€๋„ ์•Š๊ณ  ๊ฐ„๋‹จํ•˜๋‹ค. reduce๋ฅผ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์—„์ฒญ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค. 40๊ฐœ ์ด์ƒ์˜ ID๋ฅผ ๊ฐ€์ง„ ๋ฐฐ์—ด์ด ์žˆ๊ณ  reduce๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ณด๋ผ.

๊ฒฐ๋ก 

map, filter, reduce๋ฅผ ์ •๋ง ๋ฉ‹์ง€๊ณ  ์ฐฝ์˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฑธ ๋ดค๋‹ค. ๋ฉ‹์ง€๊ณ  ์ฐฝ์˜์ ์ธ ์˜ˆ๋“ค์€ reduce๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด์—ˆ์„ ๋ฟ์ด์ง€๋งŒ.. ๋งŒ์•ฝ map, filter, reduce๊ฐ€ ์‚ฌ์šฉ๋œ ํฅ๋ฏธ๋กœ์šด ๋ฐฉ๋ฒ•๋“ค์„ ๋ฐœ๊ฒฌํ•˜๋ฉด ๊ณต์œ ํ•ด ์ฃผ๊ธธ ๋ฐ”๋ž€๋‹ค. ์ด 3๊ฐ€์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์šฉ์ ์ธ ๋ฐฉ๋ฒ•๋“ค์ด ๋งŽ์ด ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•œ๋‹ค!