← Back to context

Comment by xp84

12 hours ago

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.

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

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.