As I have been leveling up my Ruby skills and knowledge, I’ve discovered that there are many concepts that I still don’t have a strong grasp on. One example is the inject instance method in the Enumerable module.

What I thought

I thought that inject did something similar to collect:

array = [1, 2, 3]

array.collect {|num| num + 1 }
# => [2, 3, 4]

With collect any block it is passed is executed on each element of the array, and a new array is returned with the updated values.

inject behaves much differently. It starts with a value, and updates that value for each element of the array.

array = [1, 2, 3]

# Set the initial value to 0, and pass it into the block as the "sum",
# since this is the variable that will be updated on each iteration and
# returned at the end of the loop.
array.inject(0) {|sum, element| sum + element}
# => 6

I found an awesome visualization of what inject does, that will shed some light on what is really happening.

If the visualization isn’t enough, here is a deeper look at what is going on.

# The original sum value. This is what was passed in as an argument to inject
result = 0

# Stores the block that we would call with the inject method
block = lambda {|sum, element| sum + element}

# For each element of the array, set the "result" variable to the value
# of calling the block with the result as the sum, and the current
# number in the loop.
array.each do |num|
  result = block.call(result, num)
end

result
# => 6

Using inject is helpful when you find yourself doing what I just demonstrated: starting with some empty value, changing that value in a loop, and returning it afterwards.