Ruby语法:从'each ... do ..'块中突破

问题描述 投票:42回答:4

我正在开发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区块(如果eachcar.name参数相同,则打破name区块)并返回导致真实结果的car。如何在Ruby代码中突破?

ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1
4个回答
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#detectArray#any?


11
投票

我提供了一个糟糕的示例代码。我不是直接从数据库中找到或检查的东西。如果某些条件遇到一次并返回导致真实结果的“汽车”,我只需要一种方法从“每个”块中突破。

那么你需要的是:

def check(cars, car_name)
  cars.detect { |car| car.name == car_name }
end

如果您只是想知道是否有任何带有该名称的汽车,那么您将使用Enumerable#any?。根据经验,只使用Enumerable#each来做副作用,而不是执行逻辑。


1
投票

你可以使用include?方法。

def self.check(name)
  cars.include? name
end

如果include?存在于true数组中,name将返回cars,否则它将返回false


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)
© www.soinside.com 2019 - 2024. All rights reserved.