如何在Ruby中替换for循环?

时间:2013-08-13 17:03:43

标签: ruby for-loop

在Ruby中,使用for循环是一种糟糕的风格。这通常被理解。 推荐给我的风格指南: (https://github.com/bbatsov/ruby-style-guide#source-code-layout) 表示:

“永远不要使用,除非你确切知道为什么。大部分时间都应该使用迭代器.for是按每个方式实现的(所以你要添加一个间接级别),但是有一个扭曲 - 因为没有引入新的范围(与每个范围不同),其区块中定义的变量将在其外部可见。“

给出的例子是:

arr = [1, 2, 3]

#bad
for elem in arr do
  puts elem
end

# good
arr.each { |elem| puts elem }

我已经研究过,我找不到关于如何模拟一个for循环的解释,该循环提供了一个可以传递给场所或执行算术运算的迭代值。 例如,我将替换什么:

for i in 0...size do
  puts array1[i]
  puts array2[size-1 - i]
  puts i % 2
end

如果它是一个阵列很容易,但我经常需要当前位置用于其他目的。 有一个我缺少的简单解决方案,或者需要 for 的情况。此外,我听到人们谈论 ,好像从来不需要。那么他们的解决方案是什么呢?

可以改进吗?什么是解决方案,如果有的话?感谢。

2 个答案:

答案 0 :(得分:10)

如果要迭代集合跟踪索引,请使用each_with_index

fields = ["name", "age", "height"]

fields.each_with_index do |field,i|
  puts "#{i}. #{field}" # 0. name, 1. age, 2. height
end

您的for i in 0...size示例变为:

array1.each_with_index do |item, i|
  puts item
  puts array2[size-1 - i]
  puts i % 2
end

答案 1 :(得分:3)

不要忘记你也可以做这样的酷事

fields = ["name", "age", "height"]

def output name, idx
  puts "#{idx}. #{name}"
end

fields.each_with_index &method(:output)

输出

0. name
1. age
2. height

您也可以将此技术用作类或实例方法

class Printer
  def self.output data
    puts "raw: #{data}"
  end
end

class Kanon < Printer
  def initialize prefix
    @prefix = prefix
  end
  def output data
    puts "#{@prefix}: #{data}"
  end
end

def print printer, data
  # separating the block from `each` allows
  # you to do interesting things
  data.each &printer.method(:output)
end

使用类方法

的示例
print Printer, ["a", "b", "c"]
# raw: a
# raw: b
# raw: c

使用实例方法

的示例
kanon = Kanon.new "kanon prints pretty"
print kanon, ["a", "b", "c"]
# kanon prints pretty: a
# kanon prints pretty: b
# kanon prints pretty: c