Last active
January 20, 2016 17:29
-
-
Save tabruhn/66b9e54572430e4ad15c to your computer and use it in GitHub Desktop.
Function to get correct change from a register.
This file contains hidden or 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
| /** | |
| * Airbnb Style Guide refactor | |
| * - set of pure composable functions for returning change of an amount from a register | |
| * - all functions are pure, self-containing, side-effect free... enforcing the Airbnb immutable rule | |
| * - each function is referential transparent, testable, parallelizable, cacheable | |
| */ | |
| /** | |
| * takes an amount, an initial list, and a list of coins | |
| * returns the list of change coins | |
| * > getChange(20,[],[25,10,10,5]) // [10,10] | |
| * > getChange(20,[],convertRegisterToList([{25:1},{10:2},{5:1}])) //[10,10] | |
| */ | |
| function getChange(amount, list, coins) { | |
| if (!coins.length || !amount) { | |
| return list; | |
| } | |
| const [head, ...tail] = coins; | |
| if (head > amount) { | |
| return getChange(amount, list, tail); | |
| } else { | |
| return getChange(amount - head, list.concat([head]), tail); | |
| } | |
| } | |
| /** | |
| * takes an array of coin objects and returns an array of coin values | |
| * > converstRegisterToList([{value:25,amount:2},{value:10,amount:2},{value:5,amount:1}]) // [25,25,10,10,5] | |
| */ | |
| function convertRegisterToList(register){ | |
| return flatten(register.map(getCoinsList)); | |
| } | |
| /** | |
| * takes a list of values and returns an array of objects with counts of those values | |
| * > getCoinObjects([25,25,10,10,5]) // [{value:25,amount:2},{value:10,amount:2},{value:5,amount:1}] | |
| */ | |
| function getCoinObjects(list){ | |
| return getUnique(list).map((item) => { | |
| return { | |
| 'value' : item, | |
| 'amount': list.filter(x => x === item).length | |
| }; | |
| }); | |
| } | |
| /** | |
| * > getCoinsList({value:25,amount:2}) // [25,25] | |
| */ | |
| function getCoinsList(coin) { | |
| function addItemsToList(amount, item, list) { | |
| if(amount > 0){ | |
| return addItemsToList(amount - 1, item, list.concat([item])); | |
| } else { | |
| return list; | |
| } | |
| } | |
| // Destructure a coin object value and amount | |
| const {value, amount} = coin; | |
| return addItemsToList(amount, value, []); | |
| } | |
| /** | |
| * Takes a list of nested lists and flattens it | |
| * > flatten([[25,25], [10,10], [1]]) // [25,25,10,10,1] | |
| */ | |
| function flatten(list) { | |
| return [].concat.apply([], list); | |
| } | |
| /** | |
| * Takes two lists, the second list being a subset of the first | |
| * returns a new list containing the difference of the two lists | |
| * > diff([25,25,25,10,10], [25,10]) // [25,25,10] | |
| */ | |
| function diff(list1,list2){ | |
| if (!list2.length) { | |
| return list1; | |
| } | |
| const [head, ...tail] = list2; | |
| return diff(pluck(list1, head), tail); | |
| } | |
| /** | |
| * > pluck([1,2,3],1)); //[2,3] | |
| */ | |
| function pluck(array, value) { | |
| const index = array.indexOf(value); | |
| if (index !== -1) { | |
| return [...array.slice(0, index), ...array.slice(index + 1)]; | |
| } | |
| return array; | |
| } | |
| /** | |
| * Takes a list and returns only the unique values of that list | |
| * > getUnique([25,25,10,10,5]) // [25,10,5] | |
| */ | |
| function getUnique (list) { | |
| return [...new Set(list)]; | |
| } | |
| /** | |
| * sums a set of numbers | |
| * > sum([25,25,10,10,5]) //75 | |
| */ | |
| function sum (list) { | |
| return list.reduce((previous, current) => { | |
| return previous + current; | |
| }, 0); | |
| } | |
| /** | |
| * Example usage | |
| */ | |
| // add values to the register | |
| const register = [{value:25, amount:2},{value:10, amount:2},{value:5, amount:5}]; | |
| // amount to return in change | |
| const amt = 55; | |
| console.log('Return coins of value ',amt,'from',JSON.stringify(register)); | |
| const change = getChange(amt,[],convertRegisterToList(register)); | |
| console.log('Coins returned:', JSON.stringify(getCoinObjects(change))); | |
| console.log('Remaining register:', JSON.stringify(getCoinObjects(diff(convertRegisterToList(register), change)))); | |
| console.log('Registers remaining value:', sum(diff(convertRegisterToList(register), change))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment