我必须编写一个Ruby方法:
迭代一个数组,如果其中一个元素匹配某个条件,则执行Foo.
如果没有数组元素符合条件,请执行Bar事务.
在任何其他语言中,我在进入循环之前设置一个布尔变量,如果我做了Foo,则切换它.该变量的值将告诉我是否需要Bar.但这感觉非常不优雅.任何人都可以提出更好的方法吗?
编辑一些非常好的答案,但由于我应该提到的细节,它们不能很好地工作.Foo所做的事情是对匹配条件的数组元素完成的.此外,它保证最多一个元素将匹配条件.
这些物品是否匹配?如果是,那么做一些事情,不涉及匹配的项目.
if items.any? { |item| item.totally_awesome? }
foo "we're totally awesome!"
else
bar "not awesome :("
end
Run Code Online (Sandbox Code Playgroud)
抓住第一个匹配的项目.如果它存在,那么使用匹配项执行某些操作.
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
Run Code Online (Sandbox Code Playgroud)
抓住所有匹配的项目.如果数组中包含任何内容,则对所有匹配项执行某些操作.
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
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
if array.any? { |elem| elem.condition }
foo
else
bar
end
Run Code Online (Sandbox Code Playgroud)
从文档中,Enumerable#any执行以下操作:
将集合的每个元素传递给给定的块.如果块返回false或nil以外的值,则该方法返回true.
你想要的是Enumerable#find
例如:
element = array.find { |x| x.passes_requirements? }
element ? element.foo! : bar
Run Code Online (Sandbox Code Playgroud)
感谢所有试图回答这个问题的人。你们都没有提供我认为合适的答案,但你们都迫使我思考如何以 Ruby 方式做事(这是本练习的要点!),并帮助我得出了这个答案:
我需要利用 Ruby 中的迭代器只是方法这一事实。所有方法都会返回一个值,并且(奇怪的是)each返回一个有用的值。如果迭代完成,它将返回您正在迭代的集合;如果您用于break提前终止迭代,它将返回nil(或可选参数)。
因此,在布尔上下文中,整个循环是true指它是否完成以及false是否退出。因此
bar if array.each do |element|
if fooable(element) then
foo(element)
break
end
end
Run Code Online (Sandbox Code Playgroud)