const { map, filter, compose, transduce } = require('ramda');
// utils
const timeIt = (label, fn) => {
console.time(label);
fn();
console.timeEnd(label);
};
const getRange = n => [...Array(n).keys()]
// data
const users = getRange(1000000).map((_, index) => ({
registered: index % 2 === 0,
discount: 1,
}))
// helpers
const isRegistered = user => user.registered; // predicate
const getDiscount = user => user.discount; // transform
// transduce reverse the compose hence we reversed the order
const getDiscountForRegisteredUsers = compose(filter(isRegistered), map(getDiscount));
const totalDiscountReducer = (totalDiscount, discount) => totalDiscount + discount; // reducer
// elegant and efficient way to get total discount
const getTotalDiscountForRegisteredUsers = () => transduce(
getDiscountForRegisteredUsers,
totalDiscountReducer,
0,
users
)
// elegant way to get total discount
const getTotalDiscountForRegisteredUsersElegantly = () => users
.filter(isRegistered)
.map(getDiscount)
.reduce(totalDiscountReducer, 0)
// efficient way to get total discount
const getTotalDiscountForRegisteredUsersEfficiently = () => {
let totalDiscount = 0;
users.forEach(user => {
if(user.registered) totalDiscount += user.discount;
})
return totalDiscount;
}
timeIt('Loop(Efficient)', getTotalDiscountForRegisteredUsersEfficiently)
timeIt('Chaining(Elegant)', getTotalDiscountForRegisteredUsersElegantly)
timeIt('Transduce(Efficient and Elegant)', getTotalDiscountForRegisteredUsers)