Last active
August 29, 2015 13:57
-
-
Save aesnyder/9403886 to your computer and use it in GitHub Desktop.
Functional Chaining in CoffeeScript and Underscore.js
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
# ob - a chainable object helper | |
# | |
# ob({foo:1, bar: 2, zap: undefined}) | |
# .compact() | |
# .map((v) -> v + 1) | |
# .value | |
# | |
# // {foo:2, bar: 3} | |
ob = (obj) -> | |
value: _.clone obj | |
map: (cb) -> | |
@value = _.object _.keys(@value), _.map @value, cb | |
this | |
compact: -> | |
c = _.clone @value | |
_.each c, (v, k) -> | |
if not v then delete c[k] | |
@value = c | |
this | |
# sum - chainable adding machine, can add either an array of numbers or array of objects with numerical properties | |
# sum([1,2,3]).value // 6 | |
# sum({f:1, b: 1},{f:2, b: 2}, {f:3, b: 2}).value // {foo: 6, bar: 5} | |
# sum({f:1, b: 1},{f:2, b: 2}, {f:3, b: 2}).by('bar').value // 5 | |
sum = (array) -> | |
reduectionStrategy = (type) -> | |
if type is 'object' | |
numbers = _.map array, (obj) -> | |
ob(obj) | |
.map (v) -> v if typeof v is 'number' | |
.compact() | |
.value | |
[numbers, ((s, n) -> ob(n).map((v, k) -> s[k] + v).value), ob(numbers[0]).map(-> 0).value] | |
else if type is 'number' | |
[array, ((s, n) -> s + n), 0] | |
value: _.reduce.apply this, reduectionStrategy(typeof array[0]) | |
by: (prop) -> | |
@value = @value[prop] | |
this |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey thanks,
Yeah functional is pretty awesome. I had read about half of the Functional Javascript book, I just picked it back up and am going to finish it this week.
all of this started with one function
Then I made sum to try to abstract this into a higher level concept and in doing that I ended up abstracting parts of it out int 'ob'. To be honest I felt the same way about the monolithic and surprising nature of sum. I think that in reality this behavior could be moved into ob as reduce as it operates in the same manner as ob's map function.
Thoughts?