Ruby 零基础教程

Ruby for 循环与迭代

使用 for 循环允许你针对序列中的每一个元素重复执行一段代码块。

本章将基于你之前对控制流的理解,提供一份在 Ruby 中使用 for 循环的全面指南,并为你学习更高级的循环技巧做好准备。

1. 了解 for 循环的基础知识

Ruby 中的 for 循环提供了一种简洁的方式来遍历项目集合,例如数组(arrays)或范围(ranges)。其基本语法如下:

for variable in collection do
  # 针对集合中每个项目要执行的代码
end

让我们逐一拆解各个部分:

  • for:这个关键字用于启动循环。
  • variable(变量):这是一个变量,在循环的每次迭代过程中,它将保存集合中当前项目的值。
  • in:这个关键字指定循环将遍历其后紧跟的集合元素。
  • collection(集合):这是你想要遍历的数组、范围或其他可枚举对象。
  • do:这个关键字标志着将为每个项目执行的代码块的开始。它是可选的;你可以省略它并使用换行符代替。
  • # 要执行的代码:这是针对集合中的每个项目将要执行的代码块。
  • end:这个关键字标志着循环的结束。

这里有一个遍历数字数组的简单示例:

numbers = [1, 2, 3, 4, 5]
for number in numbers do
  puts number * 2
end
# 输出:
# 2
# 4
# 6
# 8
# 10

在这个例子中,for 循环遍历了 numbers 数组。在每一次迭代中,number 变量获取数组中当前元素的值,然后执行 do...end 块内的代码,打印出该数字乘以 2 的结果。

2. 遍历 Range(范围)

for 循环也可以用来遍历数字范围。Range 是由起始值和结束值定义的一连串数字。

for i in 1..5 do
  puts "迭代次数: #{i}"
end
# 输出:
# 迭代次数: 1
# 迭代次数: 2
# 迭代次数: 3
# 迭代次数: 4
# 迭代次数: 5

在这个例子中,for 循环遍历了范围 1..5,它包含数字 1、2、3、4 和 5。在每次迭代期间,变量 i 会获取范围内的每一个数字。#{i} 这种语法叫做字符串插值,它允许你在字符串中嵌入变量的值。(这在数据类型和变量相关的模块中有所涉及)。

你也可以使用 1...5 来创建一个不包含结束值的范围(排他范围)。它会排除最后一个数字。

for i in 1...5 do
  puts "迭代次数: #{i}"
end
# 输出:
# 迭代次数: 1
# 迭代次数: 2
# 迭代次数: 3
# 迭代次数: 4

3. 省略 do 与内联语法

正如前面提到的,do 关键字是可选的。你可以省略它,直接使用换行:

numbers = [1, 2, 3, 4, 5]
for number in numbers
  puts number * 2
end

此外,如果循环体只包含一条语句,你可以使用极其紧凑的内联语法

numbers = [1, 2, 3, 4, 5]
for number in numbers do puts number * 2 end

虽然这样写更加紧凑,但它的可读性往往较差,特别是对于比较复杂的循环体,因此不建议滥用。

4. 在字符串中使用 for 循环

for 循环也可以用来遍历字符串中的每一个字符。不过,这种做法并不常见,因为 Ruby 提供了更方便的字符串操作方法。这里是一个例子:

word = "hello"
for char in word.chars do
  puts char.upcase
end
# 输出:
# H
# E
# L
# L
# O

在这个例子中,word.chars 将字符串 "hello" 转换成了一个字符数组:['h', 'e', 'l', 'l', 'o']。然后 for 循环遍历这个数组,char.upcase 将每个字符转换为大写并在打印出来。

5. 嵌套 for 循环

你可以将一个 for 循环放在另一个 for 循环内部(即嵌套),以此来遍历多个集合或创建更复杂的模式。这里有一个打印乘法表的嵌套 for 循环示例:

for i in 1..3 do
  for j in 1..3 do
    puts "#{i} * #{j} = #{i * j}"
  end
end
# 输出:
# 1 * 1 = 1
# 1 * 2 = 2
# 1 * 3 = 3
# 2 * 1 = 2
# 2 * 2 = 4
# 2 * 3 = 6
# 3 * 1 = 3
# 3 * 2 = 6
# 3 * 3 = 9

在这个例子中,外层 for 循环遍历数字 1 到 3,内层 for 循环同样遍历数字 1 到 3。对于 ij 的每一个组合,内层循环里的代码都会被执行,打印出乘法结果。

6. for 循环与其他迭代方法的对比

虽然 for 循环是 Ruby 中一种有效的迭代方式,但它们通常被认为不如其他方法(如 eachmapselectreject)具有 “Ruby 风格(Ruby-like/Idiomatic)”。这些将在后续模块中介绍的方法通常更受青睐,因为它们更加简洁和具有表现力。然而,理解 for 循环对于掌握迭代的基础知识以及阅读早期的 Ruby 代码仍然非常重要。

下面是前面乘法表例子的另一种写法,使用了 each 方法(将在后续章节详细讲解):

(1..3).each do |i|
  (1..3).each do |j|
    puts "#{i} * #{j} = #{i * j}"
  end
end

这段代码实现了与嵌套 for 循环示例完全相同的结果,但在 Ruby 开发者眼中,它的可读性更强,也更符合 Ruby 的惯用法。

7. 在 for 循环中使用 break 和 next

你可以使用 breaknext 关键字在 for 循环内部控制执行流程。这两个关键字在之前的章节中已有介绍。

  • break:该关键字会立即退出整个循环。
  • next:该关键字会跳过当前迭代,并直接进入集合中的下一个项目。

这里是一个演示使用 break 的例子:

numbers = [1, 2, 3, 4, 5]
for number in numbers do
  if number > 3
    break
  end
  puts number
end
# 输出:
# 1
# 2
# 3

在这个例子中,循环遍历 numbers 数组。当 number 大于 3 时,触发 break 语句,循环立刻终止。

这里是一个演示使用 next 的例子:

numbers = [1, 2, 3, 4, 5]
for number in numbers do
  if number % 2 == 0
    next
  end
  puts number
end
# 输出:
# 1
# 3
# 5

在这个例子中,循环遍历 numbers 数组。当 number 是偶数时(即除以 2 的余数为 0),触发 next 语句,跳过当前迭代。结果就是,只有奇数被打印了出来。