Ruby idiom to shortcircuit to return first non-nil using each and map
With Ruby 2.x lazy enumerators:
needle = haystacks.lazy.map(&:look_for_needle).reject(&:nil?).first
Or:
needle = haystacks.lazy.map(&:look_for_needle).detect { |needle| !needle.nil? }
Or:
needle = haystacks.lazy.map(&:look_for_needle).detect(&:itself)
I assume that both find_proverbial_needle_in_a_haystack
and look_for_needle
return the needle or nil
, the latter if no haystack contains the needle.
class Haystack def initialize(haystack) @haystack = haystack end # Suppose look_for_needle is defined as follows def look_for_needle @haystack.include?(:straw) && :straw end enddef find_proverbial_needle_in_a_haystack(haystacks) needle = nil # can be anything haystacks.find { |haystack| needle = haystack.look_for_needle } && needleend
find
returns the first haystack for which the block evaluates true
, or nil
if no needle is found in any haystack.
haystacks = [Haystack.new([:ball, :top]), Haystack.new([:fluff, :straw]), Haystack.new([:dog, :cat])] #=> [#<Haystack:0x007fdaaa0f6860 @haystack=[:ball, :top]>, # #<Haystack:0x007fdaaa0f67e8 @haystack=[:fluff, :straw]>, # #<Haystack:0x007fdaaa0f6590 @haystack=[:dog, :cat]>] find_proverbial_needle_in_a_haystack(haystacks) #=> :straw haystacks = [Haystack.new([:ball, :top]), Haystack.new([:fluff, :yellow_stuff]), Haystack.new([:dog, :cat])] #=> [#<Haystack:0x007fdaaa082f50 @haystack=[:ball, :top]>, # #<Haystack:0x007fdaaa082f00 @haystack=[:fluff, :yellow_stuff]>, # #<Haystack:0x007fdaaa082eb0 @haystack=[:dog, :cat]>] find_proverbial_needle_in_a_haystack(haystacks) #=> nil