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)
十一、总结 #
本章我们学习了:
- each:遍历元素
- map:转换元素
- select/reject:过滤元素
- find:查找元素
- reduce:聚合元素
- 其他迭代器:any?、all?、count、sum、min、max、sort、group_by
- 链式调用:组合多个迭代器
- 惰性迭代器:lazy处理无限序列
接下来让我们学习Ruby的函数与方法!
最后更新:2026-03-27