有没有办法在块内分配和中断?

Is there way to assign and break within the block?

我知道我可以这样写成功:

def test_find_first_multiple_of_3
  numbers = [2, 8, 9, 27, 24, 5]
  found = nil
  numbers.each do |number|
    if number % 3 == 0
      found = number
      break
    end
  end
  assert_equal 9, found
end

街区内有什么活动吗?我错过了什么?或者根本不可能?

numbers.each { |n| n % 3 == 0 ? (found = n then break) : nil }

def test_find_first_multiple_of_3
  numbers = [2, 8, 9, 27, 24, 5]
  found = nil
  numbers.each { |n| n % 3 == 0 ? (found = n then break) : nil }
  assert_equal 9, found
end

正如其他答案所指出的,还有其他 ruby 方法可以实现您的算法目标,例如使用 .find 方法:

found = numbers.find { |n| (n % 3).zero? }

这样,您就不需要中断循环。

但是,专门回答你的问题,如果你愿意,有一些方法可以打破同一行中的循环:

  • 使用;(多语句分隔符):

    numbers.each { |n| n % 3 == 0 ? (found = n; break) : nil }
    
  • 或者把你的作业放在 break 之后,这也有效:

    numbers.each { |n| n % 3 == 0 ? (break found = n) : nil }
    

我只是在示例中使用了您的代码,但是,同样,这不是一个好的做法,因为正如@the Tin Man 所指出的那样,"hurts readability and maintenance" .

此外,正如@akuhn 所指出的,您不需要在这里使用三元。您可以简单地使用:

numbers.each { |n| break found = n if n % 3 == 0 }

** 已编辑 以包含@the Tin Man、@akuhn 和@Eric Duminil 的建议,以警告 OP 还有其他替代方案 运行他的任务,不需要打破循环。原来的答案只是为了专门回答OP的问题(一个换行符循环)而写的,没有考虑代码结构。

用常见的Ruby成语你可以写:

def test_find_first_multiple_of_3
  numbers = [2, 8, 9, 27, 24, 5]
  found = numbers.find { |n| (n % 3).zero? }

  assert_equal 9, found
end

您可以使用枚举方法 find 来查找第一个匹配项。通常你会想要使用像 cycledetecteachreject 等可枚举方法来使代码更紧凑,同时保持可理解性:

def test_find_first_multiple_of_3
  numbers = [2, 8, 9, 27, 24, 5]
  found = numbers.find { |number| number % 3 == 0 }
  assert_equal 9, found
end

是的,breaknext 都有争论。

不过,对于您的示例,最好使用 find

 founds = numbers.find { |n| n % 3 == 0 }

通常在 Ruby 中很少有理由 break 跳出循环。

您通常可以使用 find 或 Enumerable 模块提供的任何其他函数,例如 take_whiledrop_while