#each_with_object and #inject can both be used to build a hash.
For example:
matrix = [['foo', 'bar'], ['cat', 'dog']]
some_hash = matrix.inject({}) do |memo, arr|
memo[arr[0]] = arr
memo # no implicit conversion of String into Integer (TypeError) if commented out
end
p some_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]}
another_hash = matrix.each_with_object({}) do |arr, memo|
memo[arr[0]] = arr
end
p another_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]}
One of the key differences between the two is #each_with_object
keeps track of memo
through the entire iteration while #inject
sets memo
equal to the value returned by the block on each iteration.
Another difference is the order or the block parameters.
Is there some intention being communicated here? It doesn't make sense to reverse the block parameters of two similar methods.
'Why would you do that?' implies that the speaker thinks there is not a good reason for having done it. In contrast, 'Why did you do that?' implies that the speaker acknowledges that there might have been a reason for doing it and is just asking which reason was actually the cause.
Author has 3.4K answers and 2.7M answer views Updated 1y. The answer to “What will you do” will mean you are going to do something. The answer to “What would you do” means you are going to supply an answer/opinion that might include you doing something or not.
They have a different ancestry.
each_with_object
has been added to Ruby 1.9 in 2007inject
goes back to Smalltalk in 1980I guess if the language were designed with both methods from the begin they would likely expect arguments in the same order. But this is not how it happened. inject
has been around since the begin of Ruby whereas each_with_object
has been added 10 years later only.
inject
expects arguments in the same order as Smalltalk's inject:into:
collection inject: 0 into: [ :memo :each | memo + each ]
which does a left fold. You can think of the collection as a long strip of paper that is folded up from the left and the sliding window of the fold function is always the part that has already been folded plus the next element of the remaining paper strip
# (memo = 0 and 1), 2, 3, 4
# (memo = 1 and 2), 3, 4
# (memo = 3 and 3), 4
# (memo = 6 and 4)
Following the Smalltalk convention made sense back then since all the initial methods in Enumerable
are taken from Smalltalk and Matz did not want to confuse people who are familiar with Smalltalk.
Nor could anyone have the foresight to know that would happen in 2007 when each_with_object
was introduced to Ruby 1.9 and the order of argument reflects the lexical order of the method name, which is each ... object
.
And hence these two methods expect arguments in different orders for historical reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With