One-liner for "return object if found"

Viewed 108

I currently use this code to directly return an object from a function if it is found in an array:

already_existing = my_array.find { |v| ... predicate ... }
return already_existing if already_existing
# ...
# Remaining of the function should be executed if object not found

Is there an elegant way to transform that into a one-liner?

Note: Without calling find twice of course, or calling include? first then find because it would have a performance hit)

3 Answers

You could use short-circuiting.

my_array.find { |v| ... predicate ... } or begin
  # the other logic
end

But I personally would go with return existing if existing. It's a case where cure is worse than the disease.

Is there an elegant way to transform that into a one-liner?

Sure, there is! In fact, since newlines are optional in Ruby, any arbitrarily complex Ruby program can be turned into a one-liner:

already_existing = my_array.find { |v| ... predicate ... }; return already_existing if already_existing

Facets library has #find_yield method. It can help organize code as one-liner. Also this can be done with 'map.detect' combination. Basically you need to do return something that found OR call other stuff:

require "facets"
test_arrays = [[1, 2], [1, 2, 3]]

# with facets library
test_arrays.each do |my_array|
  puts my_array.find_yield{ |i| j = i + 1; j if j % 4 == 0 } || "other_logic_result"
end
# => other_logic_result
# => 4

# with pure ruby methods
test_arrays.each do |my_array|
  puts my_array.lazy.map { |i| i + 1 }.detect { |j| j % 4 == 0 } || "other_logic_result"
end
# => other_logic_result
# => 4
Related