[JS] 코드를 값으로 표현력 높히기

최정환·2021년 9월 22일
0

go

🔧 ...args인자를 받는 go함수는 reduce함수를 동작시키는데 a(0, 누산기), f(함수, 현재값)를 인자로 받는 reduce가 f(a)를 리턴값으로 args를 초기값으로 실행된다.

// const go = (...list) => {
// log(list)}	// [0,f,f,f,f]


const go = (...args) => reduce((a, f) => f(a), args);

go(0,	// 0
   a => a + 1,	// 1
   a => a + 10,// 11
   a => a + 100,// 111
  log)	// log(111)

// (0,a=>a+1) => {0=>0+1}
// (1,a=>a+10) => {1 => 1+10}
// (11,a=>a+100) => {11 => 11+100}
// log(111)

pipe

🔧 pipe는 함수들(fs) ((a,b)=>a+b, a => a+10 ...)을 받고 인자들(as) (0,1)를 받고 go()에 인자와 함수를 준다

// const go = (...list) => {
// log(list)}	// [0,f,f,f,f]


const go = (...args) => reduce((a, f) => f(a), args);

// 첫번째 함수f ((a,b)=> a+b)로 받고 나머지 ...fs
const pipe= (f, ...fs) = (...as) =>go(f(...as),...fs);

go(
  add(0, 1),
   a => a + 10,// 11
   a => a + 100,// 111
  log)	// log(111)

const f = pipe(
  (a,b) => a + b,
  a => a + 10,
  a => a + 100,);

log(f(0,1));
// pipe((a,b)=> a+b,...fs) = (0,1) => go(f(0,1),...fs)
// reduce(f(0,1), ...fs)  
// reduce(1,...fs) // 1 => 1 +10
// reduce(11,a=>a+100) // 111

curry

🔧 함수를 받아서 함수를 리턴하고 리턴된 함수가 실행되었을때 인자가 2개 이상일때 받은 함수 즉시 실행 : 2개 미만이라면 함수를 리턴한 후 이후에 받은 인자들을 합쳐서 실행

const go = (...args) => reduce((a, f) => f(a), args);

const curry = f => (a, ..._) =>_.length ? f(a, ..._) : (..._) => f(a, ..._);

const mult = curry((a,b)=> a*b);
log(mult(1)); // 인자 1개 = false인 함수
log(mult(1)(2)); // 2

const mult3 = mult(3);
log(mult3(10)); // 30



🔧 curry를 적용한 map+filter+reduce

const reduce = curry((f, acc, iter) => {
  if(!iter){
    iter = acc[Symbol.iterator]();	
      acc = iter.next().value;
    }
  for (const a of iter){
    acc = f(acc,a);
    }
  	return acc;
});

const map = curry((f, iter) => {
let res = [];
for (const a of iter){
	res.push(f(a));
}
  return res;
});

const filter = curry((f, iter) =>{
	let iter = [];
  for (const p of iter){
  	if(f(a)) res.push(a);
  }
});

// curry함수로 filter(p=>p.price < 2000 ,products)가 아래와 같이 변할수 있다.
go(
 products,
 products => filter(p => p.price < 20000)(products),
 products => map(p=>p,price)(products),
products => reduce(add,price)(products),
 log 
);

// 위와 아래는 같다.

go(
 products,
 filter(p => p.price < 20000),
 map(p=>p,price),
reduce(add,price),
 log 
);

products => filter(p => p.price < 20000)(products)

에서 그냥 filter가 되는 이유는
go 안에 있는 products가 go안 reduce (a,f) 인자 중 a로 들어가고 f는 filter가 들어가 f(a)가 원래의 역할을 할 수 있기 떄문이다.



총 수량, 총 가격

  const products = [
    {name: '반팔티', price: 15000,quanitity:1},
    {name: '긴팔티', price: 20000,quanitity:2},
    {name: '핸드폰케이스', price: 15000,quanitity:3},
    {name: '후드티', price: 30000,quanitity:4},
    {name: '바지', price: 25000,quanitity:5}
  ];

const add = (a,b) => a+b;

const sum = (f, iter) => go(
   iter,
  map(f),
   reduce(add));

log(sum(p=>p.quantity, products)); 	// 345000

// 총 수량
const total_quantity = products => go(products,
   map(p=>p.quanitity),
   reduce(add);	

// total_quantity를 sum을 이용해 간결하게                             
const total_quantity = products => sum(p=>p.quanitity,products);  
 
                                      
const total_quantity2 = pipe(
   map(p=>p.quanitity),
   reduce(add);

log(total_quantity(products));	// 15
log(total_quantity2(products)); // 15

const total_price = pipe(
   map(p=>p.price * p.quanitity ),
   reduce(add);

log(total_price(products));	// 345000

0개의 댓글