本文簡要介紹ruby語言中 Hash類
的用法。
哈希將其每個唯一鍵映射到特定值。
Hash 與 Array 有某些相似之處,但是:
-
數組索引始終是整數。
-
哈希鍵可以(幾乎)是任何對象。
哈希數據語法
哈希數據的舊語法使用“哈希火箭”=>
:
h = {:foo => 0, :bar => 1, :baz => 2}
h # => {:foo=>0, :bar=>1, :baz=>2}
或者,但僅對於作為符號的哈希鍵,您可以使用更新的 JSON-style 語法,其中每個裸詞都成為符號:
h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}
您還可以使用字符串代替裸詞:
h = {'foo': 0, 'bar': 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}
您可以混合樣式:
h = {foo: 0, :bar => 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}
但是嘗試 JSON-style 語法來獲取不是裸詞或字符串的鍵是錯誤的:
# Raises SyntaxError (syntax error, unexpected ':', expecting =>): h = {0: 'zero'}
Hash
值可以省略,這意味著該值將通過鍵的名稱從上下文中獲取:
x = 0
y = 100
h = {x:, y:}
h # => {:x=>0, :y=>100}
常見用途
您可以使用 Hash 為對象命名:
person = {name: 'Matz', language: 'Ruby'}
person # => {:name=>"Matz", :language=>"Ruby"}
您可以使用 Hash 為方法參數命名:
def some_method(hash)
p hash
end
some_method({foo: 0, bar: 1, baz: 2}) # => {:foo=>0, :bar=>1, :baz=>2}
注意:當方法調用的最後一個參數是 Hash 時,可以省略花括號:
some_method(foo: 0, bar: 1, baz: 2) # => {:foo=>0, :bar=>1, :baz=>2}
您可以使用哈希來初始化對象:
class Dev
attr_accessor :name, :language
def initialize(hash)
self.name = hash[:name]
self.language = hash[:language]
end
end
matz = Dev.new(name: 'Matz', language: 'Ruby')
matz # => #<Dev: @name="Matz", @language="Ruby">
創建哈希
您可以使用以下命令顯式創建 Hash 對象:
-
一個hash literal。
您可以使用以下方法將某些對象轉換為哈希:
-
方法Hash。
您可以通過調用方法 Hash.new
創建一個哈希。
創建一個空哈希:
h = Hash.new
h # => {}
h.class # => Hash
您可以通過調用方法 Hash.[]
創建一個哈希。
創建一個空哈希:
h = Hash[]
h # => {}
創建一個帶有初始條目的哈希:
h = Hash[foo: 0, bar: 1, baz: 2]
h # => {:foo=>0, :bar=>1, :baz=>2}
您可以使用其文字形式(大括號)創建一個 Hash。
創建一個空哈希:
h = {}
h # => {}
創建一個帶有初始條目的哈希:
h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}
哈希值基礎
檢索哈希值的最簡單方法(實例方法 []
):
h = {foo: 0, bar: 1, baz: 2}
h[:foo] # => 0
創建或更新哈希值的最簡單方法(實例方法 []=
):
h = {foo: 0, bar: 1, baz: 2}
h[:bat] = 3 # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
h[:foo] = 4 # => 4
h # => {:foo=>4, :bar=>1, :baz=>2, :bat=>3}
刪除哈希條目的最簡單方法(實例方法 delete
):
h = {foo: 0, bar: 1, baz: 2}
h.delete(:bar) # => 1
h # => {:foo=>0, :baz=>2}
入場令
Hash 對象按其創建順序顯示其條目。這可見於:
-
迭代方法,例如
each
、each_key
、each_pair
、each_value
。 -
其他順序敏感的方法,例如
shift
、keys
、values
。 -
方法
inspect
返回的字符串。
根據給定條目,新哈希具有其初始排序:
h = Hash[foo: 0, bar: 1]
h # => {:foo=>0, :bar=>1}
最後添加新條目:
h[:baz] = 2
h # => {:foo=>0, :bar=>1, :baz=>2}
更新值不會影響順序:
h[:baz] = 3
h # => {:foo=>0, :bar=>1, :baz=>3}
但是重新創建已刪除的條目可能會影響順序:
h.delete(:foo)
h[:foo] = 5
h # => {:bar=>1, :baz=>3, :foo=>5}
哈希鍵
哈希鍵等價
當兩個對象的hash
值相同並且兩個對象彼此為eql?
時,兩個對象被視為相同的哈希鍵。
修改活動哈希鍵
在使用時修改哈希鍵會損壞哈希的索引。
此哈希具有數組鍵:
a0 = [ :foo, :bar ]
a1 = [ :baz, :bat ]
h = {a0 => 0, a1 => 1}
h.include?(a0) # => true
h[a0] # => 0
a0.hash # => 110002110
修改數組元素a0[0]
會改變其哈希值:
a0[0] = :bam
a0.hash # => 1069447059
並損壞哈希索引:
h.include?(a0) # => false
h[a0] # => nil
您可以使用方法 rehash
修複哈希索引:
h.rehash # => {[:bam, :bar]=>0, [:baz, :bat]=>1}
h.include?(a0) # => true
h[a0] # => 0
字符串鍵始終是安全的。這是因為作為鍵傳遞的未凍結字符串將被重複和凍結的字符串替換:
s = 'foo'
s.frozen? # => false
h = {s => 0}
first_key = h.keys.first
first_key.frozen? # => true
用戶定義的哈希鍵
要用作哈希鍵,對象必須實現方法 hash
和 eql?
。注意:如果哈希使用 compare_by_identity
,則此要求不適用,因為比較將依賴於鍵的對象 id 而不是 hash
和 eql?
。
Object 定義了hash
和eq?
的基本實現,使每個對象成為不同的鍵。通常,用戶定義的類將希望覆蓋這些方法以提供有意義的行為,或者例如繼承對這些具有有用定義的 Struct。
hash
的典型實現基於對象的數據,而 eql?
通常別名為重寫的 ==
方法:
class Book
attr_reader :author, :title
def initialize(author, title)
@author = author
@title = title
end
def ==(other)
self.class === other &&
other.author == @author &&
other.title == @title
end
alias eql? ==
def hash
@author.hash ^ @title.hash # XOR
end
end
book1 = Book.new 'matz', 'Ruby in a Nutshell'
book2 = Book.new 'matz', 'Ruby in a Nutshell'
reviews = {}
reviews[book1] = 'Great reference!'
reviews[book2] = 'Nice and compact!'
reviews.length #=> 1
默認值
[]
、 values_at
和 dig
方法需要返回與某個鍵關聯的值。當未找到該鍵時,該值將由其默認 proc(如果有)或默認值(最初為“nil”)確定。
您可以使用方法 default
檢索默認值:
h = Hash.new
h.default # => nil
您可以通過將參數傳遞給方法 Hash.new
或使用方法 default=
來設置默認值
h = Hash.new(-1)
h.default # => -1
h.default = 0
h.default # => 0
當未找到 key 時,將為 []
、 values_at
和 dig
返回此默認值:
counts = {foo: 42}
counts.default # => nil (default)
counts[:foo] = 42
counts[:bar] # => nil
counts.default = 0
counts[:bar] # => 0
counts.values_at(:foo, :bar, :baz) # => [42, 0, 0]
counts.dig(:bar) # => 0
請注意,使用默認值而不重複。不建議將默認值設置為可變對象:
synonyms = Hash.new([])
synonyms[:hello] # => []
synonyms[:hello] << :hi # => [:hi], but this mutates the default!
synonyms.default # => [:hi]
synonyms[:world] << :universe
synonyms[:world] # => [:hi, :universe], oops
synonyms.keys # => [], oops
要將可變對象用作默認值,建議使用默認 proc
默認過程
當設置了 Hash 的默認 proc 時(即不是 nil
),方法 []
返回的默認值僅由默認 proc 確定。
您可以使用方法 default_proc
檢索默認過程:
h = Hash.new
h.default_proc # => nil
您可以通過使用塊調用 Hash.new
或調用方法 default_proc=
來設置默認過程
h = Hash.new { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = proc { |hash, key| "Default value for #{key.inspect}" }
h.default_proc.class # => Proc
當設置了默認過程(即不是 nil
)並且使用不存在的鍵調用方法 []
時, []
使用 Hash 對象本身和缺少的鍵調用默認過程,然後返回proc的返回值:
h = Hash.new { |hash, key| "Default value for #{key}" }
h[:nosuch] # => "Default value for nosuch"
請注意,在上麵的示例中,沒有為鍵 :nosuch
創建條目:
h.include?(:nosuch) # => false
但是,proc 本身可以添加一個新條目:
synonyms = Hash.new { |hash, key| hash[key] = [] }
synonyms.include?(:hello) # => false
synonyms[:hello] << :hi # => [:hi]
synonyms[:world] << :universe # => [:universe]
synonyms.keys # => [:hello, :world]
請注意,設置默認 proc 將清除默認值,反之亦然。
這裏有什麽
首先,其他地方有什麽。類哈希:
-
繼承自 class Object 。
-
包括 module Enumerable ,它提供了許多附加方法。
在這裏,類 Hash 提供了有用的方法:
類 Hash 還包括來自模塊 Enumerable
的方法。
創建哈希的方法
- Hash[]
-
返回用給定對象填充的新哈希。
- Hash.new
-
返回一個新的空哈希。
::try_convert
-
返回從給定對象創建的新哈希。
設置哈希狀態的方法
- Hash.compare_by_identity
-
設置
self
以在比較鍵時僅考慮身份。 - Hash.default =
-
將默認值設置為給定值。
- Hash.default_proc =
-
將默認 proc 設置為給定的 proc。
rehash
-
通過重新計算每個鍵的哈希索引來重建哈希表。
查詢方法
- Hash.any?
-
返回是否有任何元素滿足給定條件。
compare_by_identity?
-
返回比較鍵時哈希是否隻考慮身份。
- Hash.default
-
返回默認值,或給定鍵的默認值。
- Hash.default_proc
-
返回默認過程。
- Hash.empty?
-
返回是否沒有條目。
- Hash.eql? object
-
返回給定對象是否等於
self
。 - Hash.hash
-
返回整數哈希碼。
has_value?
-
返回給定對象是否是
self
中的值。 -
include?
,has_key?
,member?
,key?
-
返回給定對象是否是
self
中的鍵。 -
length
,size
-
返回條目數。
value?
-
返回給定對象是否是
self
中的值。
比較方法
- #
返回
self
是否是給定對象的真子集。- #
返回
self
是否是給定對象的子集。- #==
返回給定對象是否等於
self
。- #>
返回
self
是否是給定對象的正確超集- #>=
返回
self
是否是給定對象的正確超集。
獲取方法
- Hash.hash[key]
-
返回與給定鍵關聯的值。
- Hash.assoc
-
返回包含給定鍵及其值的 2 元素數組。
- Hash.dig
-
返回由給定鍵和附加參數指定的嵌套對象中的對象。
- Hash.fetch
-
返回給定鍵的值。
- Hash.fetch_values
-
返回包含與給定鍵關聯的值的數組。
- Hash.key
-
返回具有給定值的first-found 條目的鍵。
- Hash.keys
-
返回包含
self
中所有鍵的數組。 - Hash.rassoc
-
返回一個 2 元素數組,該數組由具有給定值的 first-found 條目的鍵和值組成。
- Hash.values
-
返回一個包含
self
中所有值的數組/ - Hash.values_at
-
返回一個包含給定鍵值的數組。
分配方法
-
[]=
,store
-
將給定鍵與給定值相關聯。
- Hash.merge
-
返回通過將每個給定哈希合並到
self
的副本中形成的哈希。 -
merge!
,update
-
將每個給定的哈希合並到
self
中。 - Hash.replace
-
將
self
的全部內容替換為 givan 哈希的內容。
刪除方法
這些方法從 self
中刪除條目:
clear
-
從
self
中刪除所有條目。 - Hash.compact!
-
從
self
中刪除所有nil
值條目。 - Hash.delete
-
刪除給定鍵的條目。
- Hash.delete_if
-
刪除給定塊選擇的條目。
-
filter!
,select!
-
僅保留給定塊選擇的那些條目。
- Hash.keep_if
-
僅保留給定塊選擇的那些條目。
- Hash.reject!
-
刪除給定塊選擇的條目。
- Hash.shift
-
刪除並返回第一個條目。
這些方法返回 self
的副本,其中刪除了一些條目:
- Hash.compact
-
返回
self
的副本,其中刪除了所有nil
值條目。 - Hash.except
-
返回
self
的副本,其中刪除了指定鍵的條目。 -
filter
,select
-
返回
self
的副本,其中僅包含給定塊選擇的條目。 - Hash.reject
-
返回
self
的副本,其中刪除了給定塊指定的條目。 - Hash.slice
-
返回包含給定鍵的條目的哈希。
迭代方法
-
each
,each_pair
-
使用每個鍵值對調用給定塊。
- Hash.each_key
-
使用每個鍵調用給定的塊。
- Hash.each_value
-
使用每個值調用給定塊。
轉換方法
-
inspect
,to_s
-
返回包含哈希條目的新
String
。 - Hash.to_a
-
返回一個新的 2 元素數組;每個嵌套數組都包含一個來自
self
的鍵值對。 - Hash.to_h
-
如果是哈希,則返回
self
;如果是 Hash 的子類,則返回包含來自self
的條目的 Hash。 to_hash
-
返回
self
。 - Hash.to_proc
-
返回一個將給定鍵映射到其值的過程。
轉換鍵和值的方法
- Hash.transform_keys
-
返回帶有修改鍵的
self
的副本。 transform_keys!
-
修改
self
中的鍵 - Hash.transform_values
-
返回帶有修改值的
self
的副本。 - Hash.transform_values!
-
修改
self
中的值。
其他方法
- Hash.flatten
-
返回一個數組,它是
self
的一維展平。 - Hash.invert
-
返回每個鍵值對反轉的哈希。
相關用法
- Ruby Hash.reject用法及代碼示例
- Ruby Hash shift()用法及代碼示例
- Ruby Hash.delete()用法及代碼示例
- Ruby Hash length()用法及代碼示例
- Ruby Hash.new用法及代碼示例
- Ruby Hash.size用法及代碼示例
- Ruby Hash rehash用法及代碼示例
- Ruby Hash.delete用法及代碼示例
- Ruby Hash.hash <=用法及代碼示例
- Ruby Hash size()用法及代碼示例
- Ruby Hash each_pair()用法及代碼示例
- Ruby Hash.select!用法及代碼示例
- Ruby Hash value?用法及代碼示例
- Ruby Hash values用法及代碼示例
- Ruby Hash.ruby2_keywords_hash用法及代碼示例
- Ruby Hash.rassoc(obj)用法及代碼示例
- Ruby Hash.to_s用法及代碼示例
- Ruby Hash.values_at()用法及代碼示例
- Ruby Hash.fetch_values()用法及代碼示例
- Ruby Hash.select用法及代碼示例
- Ruby Hash.initialize_copy用法及代碼示例
- Ruby Hash.replace用法及代碼示例
- Ruby Hash member?用法及代碼示例
- Ruby Hash each_key用法及代碼示例
- Ruby Hash dig()用法及代碼示例
注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Hash類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。