Last active
October 12, 2018 12:25
-
-
Save coryhouse/866d30b20766d662707431436234d2f5 to your computer and use it in GitHub Desktop.
Functional JS examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. Use reduce to avoid multiple iterations | |
const todoList = ['clean', 'cook', 'workout', 'nap', 'relax']; | |
// Remove any item that starts with the 'c' | |
todoList.filter(todo => todo[0] !== 'c'); | |
// Capitalize every item in the todoList | |
todoList.map(todo => todo[0].toUpperCase() + todo.substr(1)); | |
// Accomplish the above with reduce | |
// This does the same as above, but with a single iteration | |
const initialValue = []; | |
const newList = todoList.reduce((prev, cur) => { | |
if (cur[0] !== 'c') { | |
const capitalizedValue = cur[0].toUpperCase() + cur.substr(1); | |
return prev.concat(capitalizedValue); | |
} | |
return prev; | |
}, initialValue); | |
console.log(newList) | |
// Another example of using reduce to avoid multiple iterations | |
const users = [ | |
{ name: 'Jon', eyes: 'green', type: 'user', age: 23}, | |
{ name: 'Tonya', eyes: 'blue', type: 'admin', age: 53}, | |
{ name: 'Bob', eyes: 'brown', type: 'admin', age: 14}, | |
{ name: 'Jane', eyes: 'brown', type: 'user', age: 51}, | |
{ name: 'Sally', eyes: 'green', type: 'user', age: 18}, | |
{ name: 'Jon', eyes: 'blue', type: 'admin', age: 71} | |
] | |
// Could have used filter and map for this, but that would have required two iterations. | |
// So reduce was more effecient. 👍 | |
const namesAndAgesOfAdminsOver50 = users.reduce((prev, cur) => { | |
if (cur.age > 50 && cur.type === 'admin') { | |
return prev.concat({name: cur.name, age: cur.age}); | |
} | |
return prev | |
}, []) | |
console.log(namesAndAgesOfAdminsOver50) | |
// now, let's use currying so we can specify the adminsOver predicate as a separate well-named function that accepts age as a param. | |
const adminsOver = age => obj => { | |
return obj.age > age && obj.type === 'admin'; | |
} | |
// note that I had to use currying because filter wants a function. | |
// So adminsOver is partially applied with just the first param (age) specified, and returns a new function with that first param closed over. | |
const usersOver50 = users.filter(adminsOver(50)); | |
console.log(usersOver50); | |
// 3. Consider passing map a well-named func (called a function delegate). Reads nicely. | |
let jsonData = [ | |
{ id: 1, name: "Soda", price: 3.12, cost: 1.04, size: "4oz", }, | |
{ id: 2, name: "Beer", price: 6.50, cost: 2.45, size: "8oz" }, | |
{ id: 3, name: "Margarita", price: 12.99, cost: 4.45, size: "12oz" } | |
]; | |
const toMenuItem = x => ({name: x.name, price: x.price}); | |
// Note how this reads like a sentence! 👍 | |
let drinkMenu = jsonData.map(toMenuItem); | |
// 4. Use reduce to get the most expensive item | |
let mostExpensiveItem = jsonData.reduce((acc, next) => acc.price > next.price ? acc : next); | |
console.log(mostExpensiveItem) | |
// Note you can pass reduce a well named method too. This conveys intent clearly. | |
let byGreatestPrice = (item, next) => item.price > next.price ? item : next; | |
let mostExpensiveItem2 = jsonData.reduce(byGreatestPrice); // Note how the name conveys what you're reducing the array down to | |
// 5. Pipe example | |
const pipe = functions => data => { | |
return functions.reduce( | |
(value, func) => func(value), | |
data | |
); | |
} | |
let cart = [3.12, 45.15, 11.01]; | |
const addSalesTax = (total, taxRate) => (total * taxRate) + total; | |
const tally = orders => pipe([ | |
x => x.reduce((total, val) => total + val), // sum the order | |
x => addSalesTax(x, 0.09), | |
x => `Order Total = ${x.toFixed(2)}` // convert to text | |
])(orders); // Order Total = 64.62 | |
// try every, some, includes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment