是否有方法在块内分配和中断?

时间:2017-01-13 17:01:44

标签: ruby conditional ternary-operator

我知道我可以成功地写这个:

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

4 个答案:

答案 0 :(得分:4)

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

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

这样,您就不需要打破循环。

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

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

    numbers.each { |n| n % 3 == 0 ? (found = n; break) : nil }
    
  • 或者在休息后放置你的分配,这也有效:

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

我刚刚在示例中使用了您的代码,但是,这并不是一个好的实践,因为,@ Tin Man指出,“伤害可读性和维护”

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

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

**已编辑以包含来自@the Tin Man,@akuhn和@Eric Duminil的建议,以警告OP还有其他选择来执行他的任务,这不需要打破循环。最初的答案只是为了回答OP的问题(一个换行循环)而没有代码结构问题。

答案 1 :(得分:1)

使用常见的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

答案 2 :(得分:1)

是的,breaknext都会参与辩论。

尽管如此,最好使用find

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

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

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

答案 3 :(得分:0)

您可以使用可枚举方法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