Ruby 哈希
Ruby 哈希 (Hashes)
Section titled “Ruby 哈希 (Hashes)”在 Ruby 中,哈希 (Hash) 是一种由键值对(key-value pairs)组成的集合,也称为关联数组(associative array)或字典(dictionary)。它类似于数组(Array),但索引使用的是任意键(任意对象类型),而非整数索引。
从 Ruby 1.9 版本开始,哈希会保持插入顺序(insertion order)。当你遍历(iterate)一个哈希时,键值对会按照它们最初插入的顺序被取出。如果你尝试用一个不存在的键访问哈希,通常会返回 nil(除非指定了默认值 default value 或 块 block)。
创建哈希 (Hashes)
Section titled “创建哈希 (Hashes)”有几种创建哈希的方式:
// 1. 使用哈希字面量语法(最常用)empty_hash = {}name_to_age = { "Alice" => 30, "Bob" => 25, "Charlie" => 35 }
// 2. 对 Symbol 键使用新的“无火箭”语法 (Ruby 1.9+)// 这非常常见,特别是用于关键字参数。symbol_keyed_hash = { name: "David", age: 40, city: "New York" }// 等同于:{ :name => "David", :age => 40, :city => "New York" }
// 3. 使用 Hash.new 创建一个空哈希months = Hash.new
// 4. 使用 Hash.new 设置默认值(用于不存在的键)default_value_hash = Hash.new(0) # 访问缺失的键会返回 0puts default_value_hash["non_existent_key"] # => 0
// 5. 使用 Hash.new 配合块 (block) 动态计算默认值// 每次访问未知键时,都会执行该块。dynamic_default_hash = Hash.new { |hash, key| hash[key] = "Default for #{key}" }puts dynamic_default_hash["first_try"] # => "Default for first_try"puts dynamic_default_hash["first_try"] # 现在它存在了,所以返回存储的值。puts dynamic_default_hash.inspect # => {"first_try"=>"Default for first_try"}
// 6. 使用 Hash[] 类方法(作为字面量不太常用)coordinates = Hash[:x, 10, :y, 20, :z, 5]// 等同于:{ :x => 10, :y => 20, :z => 5 }哈希中的键(Keys)和值(values)可以是任何对象类型。但是,键必须是唯一的(unique)。如果你为一个已存在的键赋值,旧的值将被覆盖。
常见键类型:Symbol (:my_key) 常被优先用作键,因为它们是不可变(immutable)且内存效率高的。字符串(String,"my_key")也很常见。
哈希内置方法 (Built-in Methods)
Section titled “哈希内置方法 (Built-in Methods)”哈希拥有一系列丰富的方法用于操作。假设 my_hash 是一个哈希对象 (Hash object):
#!/usr/bin/env ruby# frozen_string_literal: true
months = { "1" => "January", "2" => "February", "3" => "March" }
# 获取所有键keys = months.keysputs "Keys: #{keys.inspect}" # 输出: Keys: ["1", "2", "3"]
# 获取所有值values = months.valuesputs "Values: #{values.inspect}" # 输出: Values: ["January", "February", "March"]
# 遍历键值对months.each do |key, value| puts "Month number #{key} is #{value}"end以下是一些常见的公共哈希方法 (Hash methods)。有关完整列表,请参阅官方 Ruby 文档。
| ID | 方法及描述 |
|---|---|
| 1 | hash == other_hash 测试两个哈希是否相等:拥有相同的键值对数量,且每个键值对都相等(使用 == 进行比较)。 |
| 2 | hash[key] 访问与 key 关联的值。如果找不到键,返回 nil 或默认值/块的执行结果。 |
| 3 | hash[key] = value 将 value 与 key 关联。如果键已存在,则覆盖现有值。别名:store。 |
| 4 | hash.clear 从 hash 中移除所有键值对,使其变为空。 |
| 5 | hash.default(key = nil) 返回 hash 的默认值(如果找不到 key,则 hash[key] 会返回该值)。 |
| 6 | hash.default = obj 设置访问哈希中不存在的键时返回的默认值。 |
| 7 | hash.default_proc 如果 hash 是使用默认块创建的,则返回该块;否则返回 nil。 |
| 8 | hash.delete(key) 或 hash.delete(key) { |k| block_value } 删除由 key 指定的键值对。返回与该键关联的值。如果找不到该键,则返回 nil;如果提供了块,则执行该块并返回其结果。 |
| 9 | hash.delete_if { |key, value| block_condition } 删除块评估结果为 true 的键值对。返回哈希本身。别名 reject!(破坏性)。 |
| 10 | hash.each { |key, value| block } 或 hash.each_pair { |key, value| block } 遍历哈希,将每个键值对传递给块。如果没有提供块,则返回一个 Enumerator。 |
| 11 | hash.each_key { |key| block } 遍历哈希,将每个键传递给块。如果没有提供块,则返回一个 Enumerator。 |
| 12 | hash.each_value { |value| block } 遍历哈希,将每个值传递给块。如果没有提供块,则返回一个 Enumerator。 |
| 13 | hash.empty? 如果哈希不包含任何键值对,则返回 true。 |
| 14 | hash.fetch(key [, default_value]) 或 hash.fetch(key) { |k| block_value } 返回 key 对应的值。如果找不到 key,则抛出 KeyError。如果提供了 default_value,则返回该值。如果提供了块,则返回块的执行结果。 |
| 15 | hash.key?(key) 或 hash.has_key?(key) 或 hash.include?(key) 或 hash.member?(key) 如果哈希中存在给定的 key,则返回 true。 |
| 16 | hash.value?(value) 或 hash.has_value?(value) 如果哈希中存在给定的 value,则返回 true。 |
| 17 | hash.key(value) 返回给定 value 首次出现的对应键。如果没有找到匹配的值,则返回 nil。 |
| 18 | hash.invert 返回一个新哈希,该哈希由 hash 中的键和值反转创建。如果存在重复的值,将选择其中一个对应的键作为新的值(选择哪个键的行为可能因 Ruby 版本或实现而异)。 |
| 19 | hash.keys 返回一个新数组,包含 hash 中的所有键。 |
| 20 | hash.length 或 hash.size 返回哈希中键值对的数量,为一个整数。 |
| 21 | hash.merge(other_hash) 或 hash.merge(other_hash) { |key, old_val, new_val| block_value } 返回一个包含 hash 和 other_hash 内容的新哈希。如果同一个键在两个哈希中都存在,默认使用 other_hash 中的值;如果提供了块,则使用块的结果来解决冲突。 |
| 22 | hash.merge!(other_hash) 或 hash.merge!(other_hash) { |key, old_val, new_val| block_value } 与 merge 相同,但会直接修改 hash。别名:update。 |
| 23 | hash.rehash 根据每个键当前的哈希值重建哈希。当可变键(mutable keys)自插入以来其哈希值发生改变时需要使用。 |
| 24 | hash.reject { |key, value| block_condition } 返回一个新哈希,其中只包含块评估结果为 false 或 nil 的键值对。 |
| 25 | hash.reject! { |key, value| block_condition } 与 reject 相同,但会直接修改 hash。如果未进行任何更改,则返回 hash;否则返回 nil。 |
| 26 | hash.replace(other_hash) 将 hash 的内容替换为 other_hash 的内容。 |
| 27 | hash.select { |key, value| block_condition } 返回一个新哈希,其中只包含块评估结果为 true 的键值对。 |
| 28 | hash.select! { |key, value| block_condition } 与 select 相同,但会直接修改 hash。如果未进行任何更改,则返回 hash;否则返回 nil。 |
| 29 | hash.shift 从 hash 中移除第一个键值对(根据插入顺序),并将其作为包含两个元素的数组 [key, value] 返回。如果哈希为空,则返回 nil 或默认值。 |
| 30 | hash.slice(*keys) 返回一个新哈希,其中只包含指定 keys 对应的键值对 (Ruby 2.5+)。 |
| 31 | hash.transform_keys { |key| new_key } 返回一个新哈希,其键由块转换。 |
| 32 | hash.transform_keys! { |key| new_key } 与 transform_keys 相同,但会直接修改 hash。 |
| 33 | hash.transform_values { |value| new_value } 返回一个新哈希,其值由块转换。 |
| 34 | hash.transform_values! { |value| new_value } 与 transform_values 相同,但会直接修改 hash。 |
| 35 | hash.sort 或 hash.sort { |(k1,v1), (k2,v2)| block_comparison } 将 hash 转换为 [key, value] 对的嵌套数组并进行排序。默认按键排序。可以提供一个块用于自定义排序逻辑。 |
| 36 | hash.to_a 将 hash 转换为嵌套数组,其中每个内部数组都是一个 [key, value] 对。 |
| 37 | hash.to_h 或 hash.to_hash 返回 self(哈希本身)。对于转换实现了 to_h 方法的类数组对象很有用。 |
| 38 | hash.to_s 或 hash.inspect 返回哈希的字符串表示,通常适用于打印或调试。 |
| 39 | hash.values 返回一个新数组,包含 hash 中的所有值。 |
| 40 | hash.values_at(key1, key2, …) 返回一个新数组,包含与给定键关联的值。如果找不到某个键,则在该数组位置使用 nil(或默认值)。 |