【问题标题】:Is there a more idiomatic way to express how many iterations are left in my loop?有没有更惯用的方式来表达我的循环中还剩下多少次迭代?
【发布时间】:2014-12-07 08:00:02
【问题描述】:

我正在编写这样的 Ruby 循环:

iterations = 10

until iterations == 0
    unless iterations == 1
      puts "#{iterations} iterations until done"
    else
      puts "#{iterations} iteration until done"
    end

    iterations -= 1
end

puts "Done"

我想知道是否有更“Ruby 方式”来优化/编写此代码。有人有什么想法吗?

【问题讨论】:

  • 这个问题比较适合codereview.stackexchange.com
  • @GeraldSchneider 很高兴知道这个显然相当新的部分!

标签: ruby loops iteration idioms


【解决方案1】:
10.downto(1) do |iteration|
  puts "#{iteration} iteration#{'s' if iteration > 1} until done"
end
puts 'Done'

【讨论】:

  • 这是一个绝妙的答案。在所有事情中,我从来没有在字符串中包含这样的逻辑来做到这一点。非常好,尤其是保持它没有库。
【解决方案2】:
require 'active_support/inflector'

10.downto(1).each { |i| puts "#{i} #{'iteration'.pluralize(i)} until done" }
puts 'Done'

【讨论】:

  • 对不起,但我更喜欢 Unixmonkey 的回答,因为它可以用 vanilla Ruby 完成,而您的解决方案需要主动支持才能工作。不过,谢谢。
  • 是的,永远喜欢active_support,但必须为上面的纯红宝石方法提供支持。
  • @GDP2 无需道歉,只是展示另一种方法。
  • 就个人而言,我喜欢使用 ActiveSupport 之类的东西。老板想让迭代改成章鱼怎么办?愚蠢的例子,但我越能依靠别人越好。如果你愿意,你可以直接引入复数方法。
  • @JeffPrice,是的,在实际用例中我可以看到使用 ActiveSupport,但我认为对于“学习”方面,其他方面也很有指导意义。两者当然都是有价值的,并且具有真正的价值。由于您所说的,我也一直使用ActiveSupport 路径。
【解决方案3】:

使用范围对象计数向上

如果您不需要倒数,您可以通过迭代Range 对象来进一步简化。例如:

(1..10).each { |i| puts "#{i} iterations completed" }

这将打印:

1 iterations completed
2 iterations completed
3 iterations completed
4 iterations completed
5 iterations completed
6 iterations completed
7 iterations completed
8 iterations completed
9 iterations completed
10 iterations completed

反转范围

如果您已经有一个 Range 对象并且想要倒计时而无需调用 Integer#downto,您也可以反转 Range。例如:

(1..10).to_a.reverse.each  { |i| puts i }

【讨论】:

    猜你喜欢
    • 2011-10-22
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2014-10-11
    • 2015-05-19
    • 1970-01-01
    相关资源
    最近更新 更多