Ruby迭代器 #

一、迭代器概述 #

迭代器是Ruby中最常用的遍历集合的方式,比传统循环更简洁优雅。

方法 描述
each 遍历每个元素
map 转换每个元素
select 选择符合条件的元素
reject 拒绝符合条件的元素
reduce 聚合所有元素
find 查找第一个符合条件的元素

二、each迭代器 #

2.1 基本用法 #

ruby
[1, 2, 3, 4, 5].each do |n|
  puts n
end

[1, 2, 3, 4, 5].each { |n| puts n }

2.2 带索引 #

ruby
["a", "b", "c"].each_with_index do |item, index|
  puts "#{index}: #{item}"
end

["a", "b", "c"].each.with_index do |item, index|
  puts "#{index}: #{item}"
end

2.3 遍历哈希 #

ruby
{ a: 1, b: 2, c: 3 }.each do |key, value|
  puts "#{key}: #{value}"
end

{ a: 1, b: 2, c: 3 }.each_key do |key|
  puts key
end

{ a: 1, b: 2, c: 3 }.each_value do |value|
  puts value
end

2.4 链式调用 #

ruby
[1, 2, 3, 4, 5]
  .select { |n| n.even? }
  .each { |n| puts n }

2.5 返回值 #

ruby
result = [1, 2, 3].each { |n| puts n }
result

三、map迭代器 #

3.1 基本用法 #

ruby
[1, 2, 3, 4, 5].map { |n| n * 2 }

["a", "b", "c"].map { |s| s.upcase }

3.2 简写形式 #

ruby
[1, 2, 3].map(&:to_s)
[1, 2, 3].map { |n| n.to_s }

["hello", "world"].map(&:upcase)

3.3 map vs each #

ruby
result = [1, 2, 3].each { |n| n * 2 }
result

result = [1, 2, 3].map { |n| n * 2 }
result

3.4 map! 原地修改 #

ruby
arr = [1, 2, 3]
arr.map! { |n| n * 2 }
arr

3.5 collect #

ruby
[1, 2, 3].collect { |n| n * 2 }
[1, 2, 3].map { |n| n * 2 }

3.6 实用示例 #

ruby
names = ["alice", "bob", "charlie"]
names.map(&:capitalize)

prices = [100, 200, 300]
prices.map { |p| p * 1.1 }

users = [{ name: "Alice" }, { name: "Bob" }]
users.map { |u| u[:name] }

四、select迭代器 #

4.1 基本用法 #

ruby
[1, 2, 3, 4, 5].select { |n| n.even? }

["apple", "banana", "cherry"].select { |s| s.length > 5 }

4.2 简写形式 #

ruby
[1, 2, 3, 4, 5].select(&:even?)

["hello", "", "world"].select(&:empty?)
["hello", "", "world"].reject(&:empty?)

4.3 reject #

ruby
[1, 2, 3, 4, 5].reject { |n| n.even? }

["apple", "banana", "cherry"].reject { |s| s.include?("a") }

4.4 select! 和 reject! #

ruby
arr = [1, 2, 3, 4, 5]
arr.select! { |n| n.even? }
arr

arr = [1, 2, 3, 4, 5]
arr.reject! { |n| n.even? }
arr

4.5 filter #

ruby
[1, 2, 3, 4, 5].filter { |n| n.even? }
[1, 2, 3, 4, 5].select { |n| n.even? }

4.6 实用示例 #

ruby
users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 35 }
]

users.select { |u| u[:age] > 28 }

users.reject { |u| u[:age] < 30 }

五、find迭代器 #

5.1 基本用法 #

ruby
[1, 2, 3, 4, 5].find { |n| n > 3 }

["apple", "banana", "cherry"].find { |s| s.include?("n") }

5.2 detect #

ruby
[1, 2, 3, 4, 5].detect { |n| n > 3 }
[1, 2, 3, 4, 5].find { |n| n > 3 }

5.3 find_all #

ruby
[1, 2, 3, 4, 5].find_all { |n| n > 3 }
[1, 2, 3, 4, 5].select { |n| n > 3 }

5.4 实用示例 #

ruby
users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" }
]

users.find { |u| u[:id] == 2 }

六、reduce迭代器 #

6.1 基本用法 #

ruby
[1, 2, 3, 4, 5].reduce { |sum, n| sum + n }

[1, 2, 3, 4, 5].reduce(0) { |sum, n| sum + n }

6.2 简写形式 #

ruby
[1, 2, 3, 4, 5].reduce(:+)
[1, 2, 3, 4, 5].reduce(0, :+)

[1, 2, 3, 4, 5].reduce(:*)
[1, 2, 3, 4, 5].reduce(1, :*)

6.3 inject #

ruby
[1, 2, 3, 4, 5].inject { |sum, n| sum + n }
[1, 2, 3, 4, 5].reduce { |sum, n| sum + n }

6.4 构建数据结构 #

ruby
[1, 2, 3, 4, 5].reduce({}) do |hash, n|
  hash[n] = n ** 2
  hash
end

["a", "b", "c"].reduce([]) do |arr, s|
  arr << s.upcase
end

6.5 实用示例 #

ruby
prices = [100, 200, 300]
total = prices.reduce(0) { |sum, p| sum + p }

words = ["Hello", "World"]
sentence = words.reduce("") { |s, word| s + " " + word }.strip

longest = ["apple", "banana", "cherry"].reduce do |max, word|
  word.length > max.length ? word : max
end

七、其他常用迭代器 #

7.1 any? 和 all? #

ruby
[1, 2, 3, 4, 5].any? { |n| n > 3 }
[1, 2, 3, 4, 5].any?(&:even?)

[1, 2, 3, 4, 5].all? { |n| n > 0 }
[1, 2, 3, 4, 5].all?(&:positive?)

7.2 none? 和 one? #

ruby
[1, 2, 3, 4, 5].none? { |n| n < 0 }
[1, 2, 3, 4, 5].none?(&:negative?)

[1, 2, 3, 4, 5].one? { |n| n == 3 }
[1, 2, 3, 4, 5].one? { |n| n > 4 }

7.3 count #

ruby
[1, 2, 3, 4, 5].count
[1, 2, 3, 4, 5].count { |n| n.even? }
[1, 2, 3, 4, 5].count(3)

7.4 sum #

ruby
[1, 2, 3, 4, 5].sum
[1, 2, 3, 4, 5].sum { |n| n * 2 }
["a", "b", "c"].sum("")

7.5 min 和 max #

ruby
[3, 1, 4, 1, 5, 9, 2, 6].min
[3, 1, 4, 1, 5, 9, 2, 6].max
[3, 1, 4, 1, 5, 9, 2, 6].minmax

["apple", "banana", "cherry"].min_by(&:length)
["apple", "banana", "cherry"].max_by(&:length)

7.6 sort #

ruby
[3, 1, 4, 1, 5, 9, 2, 6].sort
[3, 1, 4, 1, 5, 9, 2, 6].sort.reverse

["apple", "banana", "cherry"].sort_by(&:length)
["apple", "banana", "cherry"].sort_by { |s| -s.length }

7.7 group_by #

ruby
[1, 2, 3, 4, 5, 6].group_by { |n| n.even? }

["apple", "banana", "cherry"].group_by { |s| s[0] }

users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 25 }
]
users.group_by { |u| u[:age] }

7.8 partition #

ruby
[1, 2, 3, 4, 5, 6].partition { |n| n.even? }

even, odd = [1, 2, 3, 4, 5, 6].partition(&:even?)

7.9 first 和 last #

ruby
[1, 2, 3, 4, 5].first
[1, 2, 3, 4, 5].first(3)
[1, 2, 3, 4, 5].last
[1, 2, 3, 4, 5].last(3)

7.10 take 和 drop #

ruby
[1, 2, 3, 4, 5].take(3)
[1, 2, 3, 4, 5].drop(3)
[1, 2, 3, 4, 5].take_while { |n| n < 4 }
[1, 2, 3, 4, 5].drop_while { |n| n < 4 }

八、链式迭代器 #

8.1 基本链式 #

ruby
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  .select { |n| n.even? }
  .map { |n| n * 2 }
  .reduce(:+)

8.2 实用示例 #

ruby
users = [
  { name: "Alice", age: 25, active: true },
  { name: "Bob", age: 30, active: false },
  { name: "Charlie", age: 35, active: true }
]

active_names = users
  .select { |u| u[:active] }
  .map { |u| u[:name] }

total_age = users
  .select { |u| u[:active] }
  .reduce(0) { |sum, u| sum + u[:age] }

九、惰性迭代器 #

9.1 lazy #

ruby
(1..).lazy
     .select { |n| n.even? }
     .map { |n| n * 2 }
     .take(5)
     .to_a

9.2 无限序列 #

ruby
(1..).lazy.select(&:prime?).first(10)

(1..).lazy.map { |n| n ** 2 }.take(5).to_a

9.3 性能优化 #

ruby
large_array.lazy.select { |x| expensive_check(x) }.first(10)

十、实用示例 #

10.1 数据转换 #

ruby
data = [
  { name: "alice", score: 85 },
  { name: "bob", score: 92 },
  { name: "charlie", score: 78 }
]

result = data
  .map { |d| { name: d[:name].capitalize, score: d[:score], grade: grade(d[:score]) } }
  .select { |d| d[:score] >= 80 }
  .sort_by { |d| -d[:score] }

10.2 统计分析 #

ruby
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

stats = {
  sum: numbers.sum,
  avg: numbers.sum.to_f / numbers.size,
  min: numbers.min,
  max: numbers.max,
  count: numbers.count,
  even_count: numbers.count(&:even?)
}

10.3 分页 #

ruby
def paginate(items, page, per_page)
  items
    .drop((page - 1) * per_page)
    .take(per_page)
end

items = (1..100).to_a
paginate(items, 2, 10)

十一、总结 #

本章我们学习了:

  1. each:遍历元素
  2. map:转换元素
  3. select/reject:过滤元素
  4. find:查找元素
  5. reduce:聚合元素
  6. 其他迭代器:any?、all?、count、sum、min、max、sort、group_by
  7. 链式调用:组合多个迭代器
  8. 惰性迭代器:lazy处理无限序列

接下来让我们学习Ruby的函数与方法!

最后更新:2026-03-27