Ruby 的哈希
本章节我们学习另外一个可以组合多个的对象类——哈希,了解哈希是什么,如何创建一个哈希以及哈希对象的实例方法。
1. 什么是哈希
哈希是键值对的集合。—— 官方定义
哈希是另一种非常有用且广泛使用的东西,可用于存储其他对象。与仅作为列表的数组不同,哈希表就像字典。我们通过键(key)来查找哈希中的值(value)。好比我们有一个英汉词典,我们通过查找“hello的单词来找到中文意思"你好",此时,“hello“就是作为键,而“你好”就是值。
我们将哈希的每一对键和值称为键值对,每一个哈希可以拥有任意数量的键值对。
2. 如何创建一个哈希
与数组一样,哈希有很多创建方法,我们可以通过哈希所属 Hash 类中的new
方法来创建一个空的哈希。
实例:
> Hash.new
=> {}
我们也可以在创建哈希的时候为它赋予初始值:
实例:
> H = Hash["a" => 100, "b" => 200]
=> {"a"=>100, "b"=>200}
在 Ruby 中,我们通过使用=>
将键分配给值来创建哈希,用逗号分隔多个键值对,并用花括号将整个内容括起来。
实例:
> a = { "one" => "1", "two" => "2", "three" => "3" }
=> {"one"=>"1", "two"=>"2", "three"=>"3"}
解释:这是一个定义了3个键值对的哈希,我们可以通过 one,来找到 1,通过 two 来找到 2,也可以通过three 来找到 3。
我们更多使用标志对象(Symbol)或者字符串对象(String)来作为哈希的键。不过我们记住一点:哈希的键和值可以是任意类型的对象。
实例:
{ 1 => "eins", 2 => "zwei", 3 => "drei" }
{ :one => "eins", :two => "zwei", :three => "drei" }
{ "weights" => ["pound", "kilogram"], "lengths" => ["meter", "mile"] }
{ :de => { :one => "eins", :two => "zwei", :three => "drei" } }
解释:
- 第一个实例使用数字类型作为键,第二个则使用标志类型作为键;
- 第三个实例我们看到它的值是一个数组;
- 第四个示例我们得到一个嵌套的哈希,在哈希中我们还可以将键对应的值设置成另一个哈希。
Tips : 关于格式化:请注意,两侧的花括号内,
=>
周围以及每个逗号后都有一个空格。
经验:
标志对象(Symbol)作为键时,我们会经常使用一个新的写法,而不是使用火箭(=>
),这种写法更贴近与 JSON 的写法。
实例:
{ one: "eins", two: "zwei", three: "drei" }
# 与这种方法创建哈希是等价的
{ :one => "eins", :two => "zwei", :three => "drei" }
这种写法会让 Ruby 将键解释为 Symbol。
3. 哈希的实例方法
3.1 查找值
我们使用[]
方法,通过传入键来查找对应的值。
实例:
# 定义一个哈希
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
puts dictionary["one"]
# ---- 输出结果 ----
"eins"
当我们查找的键没有对应内容时,会返回一个nil
。
实例:
puts dictionary["four"]
# ---- 输出结果 ----
nil
另外我们很少会用到一个fetch
方法,他和[]
方法一样都可以查找某一个键的值,但是如果键对应的值不存在,会抛出异常。
实例:
puts dictionary.fetch("one")
# ---- 输出结果 ----
"eins
puts dictionary.fetch("four")
# ---- 输出结果 ----
KeyError (key not found: "four")
3.2 更改某一个键对应的值
使用[]=
方法,传入键与更改的值:
实例:
# 定义一个哈希
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
# 更改one对应的值
dictionary["one"] = "uno"
puts dictionary
# ---- 输出结果 ----
{"one"=>"uno", "two"=>"zwei", "three"=>"drei"}
您还可以通过这种方法为哈希增加键值对:
实例:
dictionary["zero"] = "null"
puts dictionary
# ---- 输出结果 ----
{"one"=>"null", "two"=>"zwei", "three"=>"drei", "zero"=>"null"}
3.3 合并两个哈希
使用merge
方法。
实例:
a = { "one" => "eins" }
b = { "two" => "zwei" }
puts a.merge(b)
puts a
# ---- 输出结果 ----
{"one"=>"eins", "two"=>"zwei"}
{"one" => "eins"}
Tips :
merge!
方法会在合并的同时,将结果赋值给原有的哈希,而merge
方法不会改变原有的哈希。
实例:
a = { "one" => "eins" }
b = { "two" => "zwei" }
puts a.merge(b)
puts a
# ---- 输出结果 ----
{"one"=>"eins", "two"=>"zwei"}
{"one"=>"eins", "two"=>"zwei"}
3.4 获得哈希拥有的所有键
keys
返回一个带有哈希知道的所有键的数组:
实例:
# 定义一个哈希
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
dictionary.keys
# ---- 输出结果 ----
["one", "two", "three"]
3.5 获得哈希拥有的所有值
values
返回一个带有哈希所有值的数组:
# 定义一个哈希
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
dictionary.values
# ---- 输出结果 ----
["eins", "zwei", "drei"]
3.6 判断是不是空哈希
使用empty?
:
实例:
{}.empty?
# ---- 输出结果 ----
true
或者使用size
或者length
方法,判断哈希的大小是否为0。
实例:
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
puts dictionary.size == 0
puts dictionary.length == 0
# ---- 输出结果 ----
false
false
3.7 删除一个键值对
通过delete
,并传入要删除的键作为参数。
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
dictionary.delete("one")
puts dictionary
# ---- 输出结果 ----
{"two"=>"zwei", "three"=>"drei"}
如果键不存在,则不会进行操作。
4. 小结
本章中我们学习了如何创建一个哈希,通过哈希如何查找值、替换值、增加值,合并哈希、删除键值对、获得哈希键或值的数组、判断是否为空。