총 수량, 총 가격
PREV: 테스트 대상 원천 데이터
books
구현 함수들
Step 1: 총 수량, 총 가격 구하기
const total_quantity = items => go(
items,//인자값으로 받은 값을 그대로 반환(1)
map(p => p.quantity),//리스트를 순회하며 각각의 객체에서 수량(p.quantity)을 꺼내어 값들을 배열로 만들어 전달(2)
reduce((a, b) => a + b),// 인자값으로 받은 배열 파라미터를 덧셈으로 축약(3)
);
const total_price = items => go(
items,
map(p => p.quantity * p.price),
reduce((a, b) => a + b),
);
log(total_price(books)); // 920000
log(total_quantity(books)); //22
JavaScript
복사
•
총 수량과 총 가격을 제대로 계산해서 출력하고 있습니다.
Step 2: go → pipe로 리팩토링
const total_quantity = pipe(
map(p => p.quantity),
reduce((a, b) => a + b),
);
const total_price = pipe(
map(p => p.quantity * p.price),
reduce((a, b) => a + b),
);
log(total_price(books));
log(total_quantity(books));
JavaScript
복사
•
기존에 인자값(items)를 받아 그대로 첫번째 인자로 넣어주는 것은 pipe로 만들어서 함수반환을 하도록 해 리팩토링 합니다.
Step 3: reduce의 인자값(a,b)⇒a+b 모듈화
const add = (a, b) => a + b;
const total_quantity = pipe(
map(p => p.quantity),
reduce(add),
);
const total_price = pipe(
map(p => p.quantity * p.price),
reduce(add),
);
log(total_price(books));
log(total_quantity(books));
JavaScript
복사
Step 4: map, reduce 함수인자 모듈화
const add = (a, b) => a + b;
const sum = (f, iter) => go(
iter,
map(f),
reduce(add));
const total_quantity = items => sum(p => p.quantity, items);
const total_price = items => sum(p=> p.quantity * p.price, items);
log(total_quantity(books));
log(total_price(books));
JavaScript
복사
•
map과 reduce를 sum이라는 함수로 모듈화 해줬고 total_quantity와 total_price함수에서는 sum함수를 호출하도록 합니다.
Step 5: Currying 함수 적용
const add = (a, b) => a + b;
const sum = curry((f, iter) => go(
iter,
map(f),
reduce(add)));
const total_quantity = sum(p => p.quantity);
const total_price = sum(p => p.quantity * p.price);
log(total_price(books));
log(total_quantity(books));
JavaScript
복사
•
Currying 을 사용하여 각각(total_price, total_quantity)에 일부 인자값을 넘겨줘어 일부분만 완성시킨 뒤 사용할 때 변동가능성이 높은 뒷 인자값을 넘겨 원하는 결과를 출력 합니다.
HTML로 출력하기
지금까지 배운 함수들을 이용하고 템플릿 리터럴을 사용해 html tag를 생성해서 붙혀봅시다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML출력해보기</title>
</head>
<body>
<table id="cart"></table>
<script>
const log = console.log;
const books = [
{ name: "자바의정석", price: 40000, quantity: 1 },
{ name: "클린아키텍처", price: 28000, quantity: 3 },
{ name: "SQL첫걸음", price: 22000, quantity: 5 },
{ name: "MFC윈도우프로그래밍", price: 35000, quantity: 4 },
{ name: "토비의스프링", price: 98000, quantity: 2 },
{ name: "친절한SQL튜닝", price: 50000, quantity: 7 },
];
</script>
<script>
/* Simple Currying function */
const curry = f => (a, ..._) => _.length ? f(a, ..._) : (..._) => f(a, ..._);
const map = curry((f, iter) => {
let res = [];
for (const i of iter) {
res.push(f(i));
}
return res;
});
const filter = curry((f, iter) => {
let res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
return res;
});
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 go = (...args) => reduce((a, f) => f(a), args);
const pipe = (...fs) => (a) => go(a, ...fs);
const add = (a, b) => a + b;
const sum = curry((f, iter) => go(
iter,
map(f),
reduce(add)));
const total_quantity = sum(p => p.quantity);
const total_price = sum(p => p.quantity * p.price);
</script>
<script>
document.querySelector('#cart').innerHTML = `
<tr>
<th>상품 이름</th>
<th>가격</th>
<th>수량</th>
<th>총 가격</th>
</tr>
${go(books, sum(p => `
<tr>
<td>${p.name}</td>
<td>${p.price}</td>
<td><input type="number" value="${p.quantity}"></td>
<td>${p.quantity}</td>
</tr>
`)
)}
<tr>
<td colspan="2">합계</td>
<td>${total_price(books)}</td>
<td>${total_quantity(books)}</td>
</tr>`
</script>
</body>
</html>
HTML
복사
•
실행결과