logoalt Hacker News

xp84yesterday at 10:20 PM2 repliesview on HN

Ruby adds an alias `inject` for reduce. The #1 way I see it used there is like this:

  some_hash = my_array.inject({}) {|accumulator, item|  ... }
But I honestly very rarely use it (by either name) outside of a couple of pasted-in snippets (that I can't recall right now) where the strategy fits exceptionally well, probably because of the dumb reason that I tend to forget which block argument comes first (accumulator, or iterated item)! With other two-item argument lists such as `Hash#map` it being `key, value` makes sense, but with reduce/inject I don't see an obvious order. And I guess I learned before it was likely that some kind of AI autocomplete would be filling the args in for me.

Replies

diegof79yesterday at 10:57 PM

The name inject and the argument order comes from Smalltalk (Ruby is heavily inspired by it). In Smalltalk arguments are part of the message name:

collection inject: aValue into: aBlock

jdouganyesterday at 11:33 PM

Ruby inject appears to be derived from Smalltalk #inject:into:

#(1 2 3 4 5 6 7) inject: 10 into: [ :sum :each | sum + each squared ].

or from your example:

someHash := myArray inject: (Dictionary new) into: [ :accumulator :item | ... ].

The way I remember the order is it reflects the assignment you'd do is a while loop, sum := sum + each.