Skip to content

Instantly share code, notes, and snippets.

@aesnyder
Last active August 29, 2015 13:57
Show Gist options
  • Save aesnyder/9403886 to your computer and use it in GitHub Desktop.
Save aesnyder/9403886 to your computer and use it in GitHub Desktop.
Functional Chaining in CoffeeScript and Underscore.js
# 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
@aesnyder
Copy link
Author

aesnyder commented Mar 7, 2014

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

reduceField = (group, field) ->
  _.reduce group, (s, n) ->
    s + n[field]
 , 0

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment