Elegant Loop Elsing in Ruby

I need to write a Ruby method that:

  • Iterates through an array, making Foo if one of the elements matches a specific condition.

  • If none of the elements in the array matches the condition, do Bar.

In any other language, I would set a boolean variable before entering the loop and switch it if I made Foo. The value of this variable will tell me if I need a Bar. But it feels unRubyishly inelegant. Can anyone suggest a better way?

Edit Some really good answers, but they do not quite work because of the detail that I should have mentioned. What Foo does is done with an array element that matches the condition. In addition, he guaranteed that no more than one element would meet the condition.

+5
source share
6 answers

Thanks to everyone who tried to answer the question. None of you gave me the answer that I thought was necessary, but all of you made me think about how you do something in ruby ​​mode (which was the highlight of this exercise!) And helped me come up with this answer:

I need to use the fact that iterators in Ruby are just methods. All methods return a value, and (oddly enough) eachreturn a useful value. If the iteration is complete, it returns the collection that you repeated; if you use breakto complete the iteration earlier, it returns nil(or an optional argument).

, true, , false, . ,

bar if array.each do |element|
  if fooable(element) then
    foo(element)
    break
  end
end
0

? , -, .

if items.any? { |item| item.totally_awesome? }
  foo "we're totally awesome!"
else
  bar "not awesome :("
end

. , - .

awesome_item = items.find { |item| item.totally_awesome? }
if awesome_item
  foo "#{awesome_item.name} is totally awesome!"
else
  bar "no items are awesome :("
end

. - , - .

awesome_items = items.find_all { |item| item.totally_awesome? }
if awesome_items.any?
  foo "#{awesome_items.size} totally awesome items!"
else
  bar "no items are awesome :("
end
+6

:

if array.any? { |elem| elem.condition }
  foo
else
  bar
end

doc, Enumerable#any :

. true, - , false nil.

+5

# find

:

element = array.find { |x| x.passes_requirements? }
element ? element.foo! : bar
+5

: .

found_index = nil
my_array.each_with_index.detect { |elem, i| elem.condition? && found_index = i }
if found_index.nil?
  do_not_found_case
else
  my_array[found_index] = some_conversion(elem)
end

, .

+1
idx = the_array.index { |i| conditional(i) }
if idx
  modify_object(the_array[idx])
else
  no_matches
end
+1

All Articles