哈希表(也叫散列表)的类.通过哈希表,您可以将一个任意类型的对象同另一个任意类型的对象联系起来.可以使用下列哈希表表达式来生成哈希表.
{a=>b, ... }
通常使用Object#hash方法来计算哈希表的值,而使用Object#eql?方法来判定索引是否相同.
若用作索引的对象的内容发生了变化,且hash方法的返回值也有所不同时,将无法取出哈希表中的值.所以Array、Hash等的实例并不面向索引对象本身. 例如,若将字符串作为索引时,将先拷贝该字符串,然后把拷贝设为只读(freeze),最后将该拷贝用作索引.若想更改索引字符串的内容时,将引发TypeError异常.
Hash[key,value,...]Hash[hash]生成新的哈希表.使用第一种形式时,参数的个数必须是偶数.(奇数位参数是索引,偶数位参数是元素值).
使用第二种形式(将一个哈希表对象指定给参数)时, 将生成并返回一个与指定哈希表相同的全新的哈希表.(生成的哈希表的默认值为nil.)
以下是从数组生成哈希表的方法示例(可能您觉得应该有更直接的方法,但实际上并没有).
由[索引, 值, ...] 型的数组变为哈希表
ary = [1,"a", 2,"b", 3,"c"]
p Hash[*ary]
# => {1=>"a", 2=>"b", 3=>"c"}
由索引和值配对出现的数组变为哈希表
alist = [[1,"a"], [2,"b"], [3,"c"]]
p Hash[*alist.flatten]
#=> {1=>"a", 2=>"b", 3=>"c"}
由索引数组和值数组配对生成哈希表(version 1.7 以后)
keys = [1, 2, 3]
vals = ["a", "b", "c"]
alist = keys.zip(vals) # 或 alist = [keys,vals].transpose
p Hash[*alist.flatten]
#=> {1=>"a", 2=>"b", 3=>"c"}
虽然索引和值都是数组,但还是无法使用(2)或(3)的方法时,只好老老实实地赋值了
h = Hash.new
alist = [[1,["a"]], [2,["b"]], [3,["c"]]]
alist.each {|k,v|
h[k] = v
}
p h
#=> {1=>["a"], 2=>["b"], 3=>["c"]}
Hash.new([ifnone])Hash.new {|hash, key| ...} ((<ruby 1.7 特性>))生成一个全新的空哈希表.若索引没有对应值时,其默认值为ifnone.您必须谨慎地处理默认值的问题(trap::Hash).
ruby 1.7 特性:若指定了块时,则块的计算值将成为默认值.每当调用无值的哈希表元素时,都会对块进行计算,然后返回其结果.而调用哈希表时的索引将被传递给该块.
# 若没有使用块时, 一旦改变默认值将会
# 影响到其他的值
h = Hash.new("foo")
p h[1] # => "foo"
p h[1] << "bar" # => "foobar"
p h[1] # => "foobar"
p h[2] # => "foobar"
# 若使用块的话,问题便会迎刃而解
h = Hash.new {|hash, key| hash[key] = "foo"}
p h[1] # => "foo"
p h[1] << "bar" # => "foobar"
p h[1] # => "foobar"
p h[2] # => "foo"
# 若元素无值时,可以(像fetch一样)抛出异常
h = Hash.new {|hash, key|
raise(IndexError, "hash[#{key}] has no value")
}
h[1]
# => hash[1] has no value (IndexError)
self[key]返回索引为key的哈希表元素的值.若该索引并未注册,则返回默认值(若未设定则为nil).若想区分该nil到底是默认值还是哈希表元素值时,请使用fetch.
self[key]=valuestore(key,value)将索引为key的元素值设为value.返回value.
clear清空哈希表的内容. 返回self.
clonedup返回一个与receiver内容一致的新哈希表. 对冻结的哈希表进行clone时将返回一个同样的冻结的哈希表.但使用dup时,将返回内容相同但却并未冻结的哈希表.
defaultdefault([key]) ((<ruby 1.7 特性>))返回哈希表的默认值.
ruby 1.7 特性: 若哈希表是通过块来取得默认值时(请参考Hash.new),可以使用第二种形式. 此时将以self和key作参数来执行块,并返回其结果. key的缺省值为nil.
default=value将哈希表的默认值设为value.若使用无对应值的索引进行搜索时,将返回该值.
返回value.
default_proc ((<ruby 1.7 特性>))返回一个Proc对象,该对象负责返回哈希表的默认值.若没有默认的Proc时将返回nil.
h = Hash.new {|h, k| }
p h.default_proc # => #<Proc:0x0x401a9ff4>
h = Hash.new(1)
p h.default_proc # => nil
delete(key)delete(key) {|key| ... }删除索引key与对应元素之间的关系.返回被删除的值.若没有值与key相对应,则返回nil.
若给出块的话,将在key匹配失败时对块进行计算,然后返回其结果.
reject {|key, value| ... }拷贝self之后对块进行计算,若计算值为真则删除相应的哈希表元素,最后返回该哈希表.
它与Enumerable#reject基本相同,不同的是它会返回哈希表.
delete_if {|key, value| ... }reject! {|key, value| ... }把key和value当做参数来计算块,若计算值为真则删除相应的元素.
通常delete_if返回self. reject!就有所不同,若未删除元素时返回nil,除此之外则返回self.
each {|key, value| ... }each_pair {|key, value| ... }以key和value为参数对块进行计算.返回self.
{:a=>1, :b=>2}.each_pair {|k, v| p [k, v]}
# => [:a, 1]
[:b, 2]
ruby 1.8 特性:
each和each_pair的块参数交接方法有所不同.
each: yield([key, val]) each_pair: yield(key, val)
因此,若只向each_pair的块参数传递了一个变量时,将出现下述警告.详情请参考yield.
{:a=>1, :b=>2}.each_pair {|a| p a }
# => -:1: warning: multiple values for a block parameter (2 for 1)
from -:1
[:a, 1]
-:1: warning: multiple values for a block parameter (2 for 1)
from -:1
[:b, 2]
each_key {|key| ... }以key为参数来计算块.返回self.
each_value {|value| ... }以value为参数来计算块.返回self.
empty?若哈希表为空则返回真.
fetch(key[, default])fetch(key) {|key| ... }返回与索引key对应的元素的值.若该索引未被注册则分为两种情况: 若给出了参数default的话,就返回它的值;若给出了块时,将返回块的计算值.除此之外将引发IndexError异常.(ruby 1.9 特性:将引发IndexError的子类异常KeyError,而不再是IndexError异常.)
has_key?(key)include?(key)key?(key)member?(key)若key是哈希表的索引则返回真.
has_value?(value)value?(value)若value是哈希表的元素值则返回真.对值进行判断时使用==操作符.
index(val)返回与val对应的索引.若无法对应时返回nil.
若有若干个对应的索引时,则会随机地返回其中之一.
indexes(key_1, ... , key_n) ((<obsolete>))indices(key_1, ... , key_n) ((<obsolete>))以数组的形式返回与参数所指的索引相对应的元素值.
ruby 1.8 特性: 该方法在version 1.8中已被禁用.使用时会出现警告信息.此时,应该使用Hash#values_at.
invert将元素值和索引互换,返回变换后的哈希表. 请注意:若原哈希表中若干不同的索引对应相同的元素值时,其变换结果将无法预测. 因为该方法原本就不是为这种情况所设计的.
h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
h.invert #=> {200=>"d", 300=>"y", 0=>"a", 100=>"n"}
keys返回一个包含所有索引的数组.
lengthsize返回哈希表中的元素的个数.
merge(other)merge(other) {|key, self_val, other_val| ... }merge!(other)merge!(other) {|key, self_val, other_val| ... }ruby 1.8 特性
Hash#merge等同于hash.dup.update.而Hash#merge!则是Hash#update的别名.
当self和other中包含相同索引时将按照下列两种方式来处理: 若带块则调用该块,然后由用户选择使用哪个值;不带块的话则通常使用other的值.
rehash重新计算索引对应的哈希表值。当与索引对应的哈希表值发生变化时,若不使用该方法来重新计算的话,将无法取出与索引对应的哈希表值。
replace(other)以other的内容来替换哈希表的内容。返回self。
shift删除一个哈希表元素后,再以[key,value]数组的形式将其返回。
当哈希表为空时,如果没有默认值default则返回nil,如果有默认值的话就返回默认值(请注意,此时并不是以[key,value]的形式返回该值的)。
h = Hash.new
p h.empty? # => true
p h[0] # => nil
p h.shift # => nil
p h.default # => nil
h.each {|v| p v} # =>
p h.to_a # => []
h1 = Hash.new("default value")
p h1.empty? # => true
p h1[0] # => "default value"
p h1.shift # => "default value"
p h1.default # => "default value"
h1.each {|v| p v} # =>
p h1.to_a # => []
# ruby 1.7 特性
h2 = Hash.new {|arg| arg}
p h2.empty? # => true
p h2[0] # => [{}, 0]
p h2.shift # => [{}, nil]
p h2.default # => [{}, nil]
h2.each {|v| p v} # =>
p h2.to_a # => []
to_a生成并返回一个数组,数组中的元素也是数组,且由[key,value]构成。
to_hash返回self。
update(other)update(other) {|key, self_val, other_val| ... } ((<ruby 1.7 特性>))合并哈希表的内容。若出现相同索引时,将使用other中对应的元素值。
ruby 1.7 特性: 若给出了块的话,每当遇到相同索引时都会对块进行计算,然后以块的计算值作为该索引的对应值。此时,索引、self[key] 和other[key]将被作为参数传递给该块。
foo = {1 => 'a', 2 => 'b', 3 => 'c'}
bar = {1 => 'A', 2 => 'B', 3 => 'C'}
p foo.dup.update(bar) # => {1=>"A", 2=>"B", 3=>"C"}
p foo.dup.update(bar) {|k,v| v} # => {1=>"a", 2=>"b", 3=>"c"}
返回self。
values返回一个包括哈希表中的所有元素值的数组。
values_at(key_1, ... , key_n)ruby 1.8 特性
返回一个数组,该数组包括与参数所指索引相对应的哈希表元素值。若没有与索引相对应的哈希表元素值时,将使用default的值。与indexes以及indices相同。
h = {1=>"a", 2=>"b", 3=>"c"}
p h.values_at(1,3,4) # => ["a", "c", nil]