Recently I wanted to pass each entry in an array to a block, and return the first non-false block result. This is the converse of Enumberable#detect, where you pass each entry to a block and return the first entry for which the block result is not false.
Put another way, it’s a lazy map plus detect.
Ruby does not evaluate its enumerations lazily, so this is how to do it:
module Enumerable
def map_detect
self.each do |item|
if result = (yield item)
return result
end
end
nil
end
end
Credit: Arnau Sánchez Sala
I want to search across several models for a particular reference number (by scanning a barcode, as it happens). The map_detect snippet above lets me write:
def search_by_code(code)
garment = [ Shirt Jacket Suit Coat ].map_detect { |klass| klass.find_by_code code }
# ...
end