我必须编写一个Ruby方法:
遍历数组,如果其中一个元素符合某个条件,则执行Foo。
如果没有数组元素符合条件,请执行Bar thing。
在任何其他语言中,我在进入循环之前设置一个布尔变量,如果我做了Foo,则切换它。该变量的值将告诉我是否需要Bar。但这感觉非常不优雅。任何人都能提出更好的建议吗?
编辑一些非常好的答案,但由于我应该提到的细节,它们不太有用。 Foo所做的事情是对匹配条件的数组元素完成的。此外,它保证最多只有一个元素符合条件。
答案 0 :(得分:6)
是否有任何项目匹配?如果是,那么做一些事情,不涉及匹配的项目。
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
答案 1 :(得分:5)
你可以这样做:
if array.any? { |elem| elem.condition }
foo
else
bar
end
从doc,Enumerable#any
执行以下操作:
将集合的每个元素传递给给定的块。如果块返回的值不是false或nil,则该方法返回true。
答案 2 :(得分:5)
你想要的是Enumerable#find
例如:
element = array.find { |x| x.passes_requirements? }
element ? element.foo! : bar
答案 3 :(得分:1)
编辑:根据新的问题标准修改。
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
这不是很漂亮,但它完成了工作,并且在第一场比赛中仍然短路。
答案 4 :(得分:1)
idx = the_array.index { |i| conditional(i) }
if idx
modify_object(the_array[idx])
else
no_matches
end
答案 5 :(得分:0)
感谢所有试图回答这个问题的人。你们没有提供我认为合适的答案,但是你们都强迫我思考你们如何用Ruby的方式做事(这是本练习的主要内容!)并帮助我提出了这个答案:
我需要利用Ruby中的迭代器只是方法这一事实。所有方法都返回一个值,(奇怪的是)each
返回有用的值。如果迭代完成,它将返回您正在迭代的集合;如果您使用break
提前终止迭代,则返回nil
(或可选参数)。
因此,在布尔上下文中,整个循环如果完成则为true
,如果突破则为false
。因此
bar if array.each do |element|
if fooable(element) then
foo(element)
break
end
end