文章目录

Ruby 数组方法:each、map、select 的使用

发布于 2026-04-06 02:20:35 · 浏览 11 次 · 评论 0 条

Ruby 数组方法:each、map、select 的使用

Ruby 的数组是日常开发中最常用的数据结构之一。熟练掌握数组的迭代方法,能让你的代码更简洁、更易读。本文将详细介绍 eachmapselect 这三个最实用的数组方法,帮你快速提升编码效率。


先理解一个核心概念:块(Block)

在学习这些方法之前,需要先理解 Ruby 的块(Block)特性。块是一段可以传递给方法的代码,用 {}do...end 包裹。

# 两种写法等效
[1, 2, 3].each { |num| puts num }
[1, 2, 3].each do |num|
  puts num
end

管道符号 | 之间的变量是块的参数,每次迭代时会接收数组中的一个元素。


each 方法:逐个处理

each 是最基础的迭代方法,用于遍历数组中的每个元素。它不会改变原数组,也不会返回新数组——它的返回值是原始数组本身。

基本用法

numbers = [1, 2, 3, 4, 5]

result = numbers.each do |num|
  puts "当前数字: #{num}"
end

puts result.inspect  # => [1, 2, 3, 4, 5]

执行后,你会看到输出依次是 当前数字: 1当前数字: 2……直到 当前数字: 5。虽然我们在块里做了操作,但 result 变量最终得到的仍是原始数组。

常见应用场景

each 适合用于执行副作用操作,比如打印日志、更新界面、写入文件等不关心返回值的场景。

users = ["Alice", "Bob", "Charlie"]

users.each { |user| puts "处理用户: #{user}" }

# 输出:
# 处理用户: Alice
# 处理用户: Bob
# 处理用户: Charlie

map 方法:转换数据

map 方法会对每个元素执行块中的操作,并将结果收集起来返回一个新数组。这是数据转换的利器。

基本用法

numbers = [1, 2, 3, 4, 5]

squares = numbers.map do |num|
  num * num
end

puts squares.inspect  # => [1, 4, 9, 16, 25]

numbers 本身没有任何变化,但 squares 是一个全新的数组,包含了每个元素的平方值。

实战示例

names = ["alice", "bob", "charlie"]

capitalized = names.map { |name| name.capitalize }
puts capitalized.inspect  # => ["Alice", "Bob", "Charlie"]

# 链式调用
ids = [101, 102, 103]
formatted = ids.map { |id| "USER-#{id}" }
puts formatted.inspect  # => ["USER-101", "USER-102", "USER-103"]

与 each 的关键区别

numbers = [1, 2, 3]

# each 返回原数组
each_result = numbers.each { |n| n * 2 }
puts each_result.inspect  # => [1, 2, 3]

# map 返回新数组
map_result = numbers.map { |n| n * 2 }
puts map_result.inspect  # => [2, 4, 6]

这个区别至关重要。each 的返回值总是被忽略的原始数组,而 map 的返回值才是我们真正想要的新数组。


select 方法:筛选元素

select 方法会根据块中的条件判断来筛选元素,返回一个只包含满足条件元素的新数组。也称为过滤操作。

基本用法

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

evens = numbers.select do |num|
  num.even?
end

puts evens.inspect  # => [2, 4, 6, 8, 10]

只有偶数被保留了下来。块的返回值必须是布尔值(truefalse),返回 true 的元素会被选中。

实战示例

products = [
  { name: "笔记本", price: 50 },
  { name: "手机", price: 3000 },
  { name: "耳机", price: 200 },
  { name: "平板", price: 2500 }
]

# 筛选价格超过 1000 的商品
expensive = products.select { |p| p[:price] > 1000 }
puts expensive.inspect
# => [{:name=>"手机", :price=>3000}, {:name=>"平板", :price=>2500}]

# 筛选名称包含"机"的产品
keyword = products.select { |p| p[:name].include?("机") }
puts keyword.inspect
# => [{:name=>"手机", :price=>3000}, {:name=>"平板", :price=>2500}]

与 map 的对比

场景 方法 作用
转换每个元素 map [1,2,3].map { \|n\| n*2 }[2,4,6]
筛选满足条件的元素 select [1,2,3].select { \|n\| n>1 }[2,3]

三者对比总结

data = [10, 20, 30, 40, 50]

# each:遍历执行,不关心返回值
data.each { |n| puts n * 2 }
# 输出: 20, 40, 60, 80, 100
# 返回: [10, 20, 30, 40, 50]

# map:转换每个元素,返回新数组
mapped = data.map { |n| n * 2 }
# 返回: [20, 40, 60, 80, 100]

# select:筛选满足条件的元素,返回新数组
filtered = data.select { |n| n > 25 }
# 返回: [30, 40, 50]

记忆口诀

  • each → 逐个一遍,不返回值
  • map映射成新值,生成新数组
  • select挑选合格的,留下筛选后的结果

组合使用:威力翻倍

这三个方法可以链式调用,处理复杂的业务逻辑。

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

# 筛选偶数 -> 平方 -> 求和
result = numbers
  .select { |n| n.even? }      # [2, 4, 6, 8, 10]
  .map { |n| n * n }           # [4, 16, 36, 64, 100]
  .sum                         # 220

puts result  # => 220
users = [
  { name: "张三", age: 25, active: true },
  { name: "李四", age: 30, active: false },
  { name: "王五", age: 28, active: true },
  { name: "赵六", age: 35, active: true }
]

# 获取所有活跃用户的名字
active_names = users
  .select { |u| u[:active] }
  .map { |u| u[:name] }

puts active_names.inspect  # => ["张三", "王五", "赵六"]

常见错误与注意事项

1. 混淆 each 和 map 的返回值

# 错误写法:想获取平方值却用了 each
numbers = [1, 2, 3]
squares = numbers.each { |n| n * n }
puts squares.inspect  # => [1, 2, 3]  不是想要的 [1, 4, 9]

# 正确写法
squares = numbers.map { |n| n * n }
puts squares.inspect  # => [1, 4, 9]

2. 在 select 中忘记返回布尔值

# 错误:返回了数值,而不是布尔值
[1, 2, 3, 4].select { |n| n * 2 }
# Ruby 会将非 nil 和非 false 都视为真,所以会返回整个数组

# 正确:明确返回判断结果
[1, 2, 3, 4].select { |n| n > 2 }  # => [3, 4]

3. 修改原数组

这三个方法都不会修改原数组。如果你想原地修改,可以使用 map!select! 等带感叹号的版本。

numbers = [1, 2, 3, 4, 5]

numbers.map! { |n| n * 2 }
puts numbers.inspect  # => [2, 4, 6, 8, 10]

选择指南

需求 推荐方法
只是遍历并执行操作(如打印、写入) each
需要对每个元素进行转换,生成新数组 map
需要根据条件筛选出部分元素 select
需要转换后继续筛选或再次转换 链式调用

掌握这三种方法后,你会发现Ruby代码变得简洁而强大。勤加练习,让它们成为你日常编码的得力工具。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文