CHAPTER 13 함수형 도구 체이닝
CHAPTER 13 함수형 도구 체이닝
여러 단계를 하나로 조합하는것을 체이닝(chaining)이라고 합니다.
체인을 명확하게 만들기 1: 단계에 이름 붙이기
function biggestPurchasesBestCustomers(customers) {
var bestCustomers = selectBestCustomers(customers);
var biggestPurchases = getBiggestPurchases(bestCustomers);
return biggestPurchases;
}
function selectBestCustomers(customers) {
return filter(customers, function(customer) {
return customer.purchases.length >= 3;
});
}
function getBiggestPurchases(customers) {
return map(customers, getBiggestPurchase);
}
체인을 명확하게 만들기 2: 콜백에 이름 붙이기
function biggestPurchasesBestCustomers(customers) {
var bestCustomers = filter(customers, isGoodCustomer);
var biggestPurchases = map(bestCustomers, getBiggestPurchase);
return biggestPurchases;
}
function isGoodCustomer(customer) {
return customer.purchases.length >= 3;
}
function getBiggestPurchase(customer) {
return maxKey(customer.purchases, {total: 0}, getPurchaseTotal);
}
체인을 명확하게 만들기 3: 두 방법을 비교
일반적으로는 콜백에 이름 붙이기가 더 명확하다
반복문을 함수형 도구로 리팩터링하기
지금 하는 것은 최적화이다 병목이 생겼을 때만 최적화를 하자
- 이해하고 다시 만들기
- 단서를 찾아 리팩터링
값 하나에 map() 두번 사용
var names = map(customers, getFullName);
var nameLengths = map(names, stringLength);
var nameLengths = map(customers, function(customer) {
return stringLength(getFullName(customer));
});
값 하나에 filter() 두번 사용
var goodCustomers = filter(customers, isGoodCustomer);
var withAddresses = filter(goodCustomers, hasAddress);
var withAddresses = filter(customers, function(customer) {
return isGoodCustomer(customer) && hasAddress(customer);
});
map() 다음에 reduce() 사용하기
var purchaseTotals = map(purchases, getPurchaseTotal);
var purchaseSum = reduce(purchaseTotals, 0, plus);
var purchaseSum = reduce(purchases, 0, function(total, purchase) {
return total + getPurchaseTotal(purchase);
});
팁 1: 데이터 만들기
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var sum = 0;
var count = 0;
for(var w = 0; w < window; w++) {
var idx = i + w;
if(idx < array.length) {
sum += array[idx];
count += 1;
}
}
answer.push(sum/count);
}
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var sum = 0;
var count = 0;
var subarray = array.slice(i, i + window);
for(var w = 0; w < subarray.length; w++) {
sum += subarray[w];
count += 1;
}
answer.push(sum/count);
}
팁 2: 한 번에 전체 배열을 조작하기
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var sum = 0;
var count = 0;
var subarray = array.slice(i, i + window);
for(var w = 0; w < subarray.length; w++) {
sum += subarray[w];
count += 1;
}
answer.push(sum/count);
}
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var subarray = array.slice(i, i + window);
answer.push(average(subarray));
}
팁 3: 작은 단계로 나누기
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var subarray = array.slice(i, i + window);
answer.push(average(subarray));
}
var indices = [];
for(var i = 0; i < array.length; i++)
indices.push(i);
var window = 5;
var answer = map(indices, function(i) {
var subarray = array.slice(i, i + window);
return average(subarray);
});
체이닝 팁 요약
- 데이터 만들기
- 배열 전체를 다루기
- 작은 단계로 나누기
- 조건문을 filter()로 바꾸기
- 유용한 함수로 추출하기
체이닝 디버깅을 위한 팁
- 구체적인 것을 유지하기
- 출력해보기
- 타입을 따라가 보기
다양한 함수형 도구
- pluck()
- cancat()
- frequenciesBy(), groupBy()