Ruby each_with_object
Tranformations are common operations on Ruby collections, map and inject are useful but there's also another handy method
I see lots of code that looks like this (long-form blocks for readability):
collection = %w[red green blue black bronze]
result = [] # <<----- hmmmm, here is my problem
collection.each do |colour|
result << colour if colour.size >= 4
end
pp result
# ["green", "blue", "black", "bronze"]
I'd normally wince at the result
object being manipulated by the each
block and yell to use map
and then a compact
to get rid of nils. There is another way. Enter Enumerable#each_with_object
.
collection = %w[red green blue black bronze]
# an object is passed to each iteration -------------++++++
# and it's created here -------------vv vvvvvv
result = collection.each_with_object([]) do |colour, result|
result << colour if colour.size >= 4
result # the return value here will be passed to the next iteration
end
pp result
# ["green", "blue", "black", "bronze"]
This is neater and I can be sure that the result
object doesn't suffer from any side-effects.
Member discussion