我正在开发 Ruby on Rails 应用。我的问题更多是关于 Ruby 语法。
我有一个带有类方法self.check
的模型类:
class Cars < ActiveRecord::Base
...
def self.check(name)
self.all.each do |car|
#if result is true, break out from the each block, and return the car how to...
result = SOME_CONDITION_MEET?(car) #not related with database
end
puts "outside the each block."
end
end
我想停止/突破each
阻止一次 result
true (这会打破{{1}如果each
与car.name
参数一次相同,则阻止,并返回导致 true 结果的name
。如何在Ruby代码中突破?
答案 0 :(得分:90)
您可以使用break
关键字。例如
[1,2,3].each do |i|
puts i
break
end
将输出1
。或者,如果要直接返回值,请使用return
。
由于您更新了问题,因此代码为:
class Car < ActiveRecord::Base
# …
def self.check(name)
self.all.each do |car|
return car if some_condition_met?(car)
end
puts "outside the each block."
end
end
虽然您也可以使用Array#detect
或Array#any?
来实现此目的。
答案 1 :(得分:11)
我提供了一个错误的示例代码。我不是直接找到或检查的东西 来自数据库。我只是需要一种方法来突破“每个”块 一些条件遇到一次并返回导致真实的“汽车” 结果
然后你需要的是:
def check(cars, car_name)
cars.detect { |car| car.name == car_name }
end
如果您只想知道是否有任何带有该名称的汽车,那么您可以使用Enumerable#any?
。根据经验,仅使用Enumerable#each
来执行副作用,而不是执行逻辑。
答案 2 :(得分:1)
您可以使用break
,但您尝试做的事情可以更轻松地完成,例如:
def self.check(name)
return false if self.find_by_name(name).nil?
return true
end
这使用数据库。您正试图在数据库可以更好地处理它的地方使用Ruby。
您还可以使用break
条件:
break if (car.name == name)
答案 3 :(得分:1)
您可以使用include?
方法。
def self.check(name)
cars.include? name
end
如果include?
数组中存在true
,则 name
会返回cars
,否则会返回false
。
答案 4 :(得分:0)
我必须做同样的事情,而且我还是空白。因此,尽管这是一个非常老的问题,但这是我的答案:
由于从积木块返回很狡猾(没人喜欢,我认为规则将要改变,这使它更加烦恼),这是一个更好的选择:
collection.inject(nil) do |_acc, item|
output = expensive_operation(item)
break output if output
end
请注意,有很多变体。例如,如果您不希望使用附带变量,并且不介意在某些情况下启动第二个循环,则可以像这样反转它:
collection.inject(nil) do |acc, item|
break acc if acc
expensive_operation(item)
end