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