Here's a handy little method I keep reaching for: map_with_index. It does exactly what you'd expect — it works like each_with_index but with the return-value behaviour of map. Every element in the resulting array is whatever the block returns when that element and its index are yielded to it.
module BarkingIguana
module ArrayExt
def map_with_index &block
index = 0
map do |element|
result = yield element, index
index += 1
result
end
end
end
end
Array.class_eval do
include BarkingIguana::ArrayExt
end
This is particularly useful when the first N elements of an array need to be treated differently from the rest:
[1, 2, 3, 4, 5].map_with_index do |element, index|
model = Model.new element
model.unlock if index < 3
model
end
Note that Ruby 1.9.3+ gives you each_with_index.map and later versions provide each_with_object and other enumerator-chaining tricks that can achieve similar results — but sometimes a purpose-built method just reads better.