你有没有理由两次遍历数组(或某种可迭代对象)?

时间:2014-06-11 04:13:04

标签: ruby iterator each

你有没有理由两次遍历数组(或某种可迭代对象)?

示例双循环:

array.each do |array_object|
  # do some stuff with array object
end.each do |array_object_other_loop|
  # do some other stuff
end

我没有看到这样的任何用法,但红宝石会允许你这样做。

2 个答案:

答案 0 :(得分:2)

您所看到的只是每个表达式在Ruby中返回值的效果。恰好each返回原始集合,因此您可以再次调用each。这并不意味着这是针对这个特定场景而设计的,但让each返回集合本身肯定是该语言的作者鼓励这样使用的标志。

我可以想到你在飞行中创建一个集合的情况,然后立即迭代它,然后再次;没有将集合写入变量。然后,只是循环遍历each内的元素的差异将是执行的顺序。例如:

%w[a b c].each do |char|
  puts char
end.each do |char|
  puts char
end

# a
# b
# c
# a
# b
# c

%w[a b c].each do |char|
  2.times do
    puts char
  end
end

# a
# a
# b
# b
# c
# c

那就是说,我们可以提出一百万个像

这样的问题
  

puts puts有什么意义吗?

当然puts也会返回原始对象,因此您可以再次puts,但肯定不是很好。 Ruby是一种非常灵活的语言,所有这些功能都可以让您自由表达您的意思。如果有疑问,请始终坚持最明显的做事方式,并尝试让代码揭示其意图。

答案 1 :(得分:2)

我想到的一个例子就是当你想要在列对齐的终端上绘制表格时。为了计算列宽,您需要遍历行一次,此时您无法进行填充。填充必须在第二次迭代中完成。

rows = ["hi", "hello", "good morning"]
column_width = 0
rows
.each{|column| column_width = [column_width, column.length].max}
.each{|column| puts "|" + column.center(column_width) + "|"}

输出:

|     hi     |
|   hello    |
|good morning|

你不能将两个each的块放在一起。