Total Cart Price: Solution Review
Solution review.
We'll cover the following
Getting Prices
Since point-free takes some getting used to, it can help to first write a plain solution and make it point-free later.
If you need a cart’s total price and each item’s shaped like this…
{
name: 'apples',
price: 2.49
}
…start by planning how you’d initially prepare the data. It’s a collection so map
can get the prices and reduce
can add them up for us.
import cart from './cart';const getTotalPrice = (items) => items.map((item) => item.price).reduce((acc, value) => acc + value, 0)const result = getTotalPrice(cart);console.log({ result });
A Touch of Formatting
We’d like a dollar figure, so 36.410000000000004 should be $36.41.
import cart from './cart';const toUSD = (amount) => amount.toLocaleString('en-US', {style: 'currency',currency: 'USD',});const getTotalPrice = (items) => {const total = items.map((item) => item.price).reduce((acc, value) => acc + value, 0);return toUSD(total);};const result = getTotalPrice(cart);console.log({ result });
Refactoring to Point-Free
What were our steps?
- Get each price
- Add them up
- Format as dollars (USD)
We know pipe
's great for multiple steps, so that’ll definitely help us get a point-free solution. And map
/reduce
are provided by Ramda.
import { map, pipe, reduce } from 'ramda';import cart from './cart';const toUSD = (amount) => amount.toLocaleString('en-US', {style: 'currency',currency: 'USD',});const getTotalPrice = pipe(map((item) => item.price),reduce((acc, value) => acc + value, 0),toUSD);const result = getTotalPrice(cart);console.log({ result });
Even though the map
/reduce
functions aren’t point-free, getTotalPrice
is. This solution’s perfectly fine so pat yourself on the back if you got it.
We can make map
/reduce
point-free though. Ramda’s prop
function grabs a given property of an object.
map(prop('price'))
And Ramda’s add
function can be put inside reduce
.
reduce(add, 0);
import { add, map, pipe, prop, reduce } from 'ramda';import cart from './cart';const toUSD = (amount) => amount.toLocaleString('en-US', {style: 'currency',currency: 'USD',});const getTotalPrice = pipe(map(prop('price')),reduce(add, 0),toUSD);const result = getTotalPrice(cart);console.log({ result });
Wait There’s More!
Plucking a property and summing a list are such common use cases that Ramda provides functions for them!
Check out pluck
and sum
.
https://ramdajs.com/docs/#pluck
https://ramdajs.com/docs/#sum
import { add, pipe, pluck, sum } from 'ramda';import cart from './cart';const toUSD = (amount) => amount.toLocaleString('en-US', {style: 'currency',currency: 'USD',});const getTotalPrice = pipe(pluck('price'),sum,toUSD);const result = getTotalPrice(cart);console.log({ result });
I personally liked this solution the most as it’s so concise and expressive. If you got this one then double-pat yourself on the back.