前言
說完陣列,就知道下一個肯定是雜湊
,在 Objective-C
裡的體現是字典(NSDictionary)
。為什麼這種集合很受歡迎呢?這要從雜湊演算法說起,簡單的說,hash
能以 O(1)的複雜度將內容對映到位置。Hash 演算法的原理和基礎概念,不乏好文,此處不贅述。後面可以專門複習梳理下。
建立雜湊
?> hash = {}
=> {}
>> hash['1'] = "one"
=> "one"
?> hash
=> {"1"=>"one"}
>>
?> h = Hash.new
=> {}
>> h['2'] = "two"
=> "two"
>> h
=> {"2"=>"two"}
複製程式碼
可以用 =>
初始化 hash
,可以叫它雜湊火箭?
(調皮)
?> h = {
?> '1' => "one",
?> '2' => "two"
>> }
=> {"1"=>"one", "2"=>"two"}
>> h
=> {"1"=>"one", "2"=>"two"}
複製程式碼
如果取沒有 key 的值,返回 nil。當然這取決於你構造時有沒有傳預設值。
?> h["3"]
=> nil
?> h = Hash.new(0)
=> {}
>> h['4']
=> 0
複製程式碼
刪除,簡單的置值為 nil 不能刪除。可以使用#delete
方法
?> h = {'1' => "one", '2' => "two"}
=> {"1"=>"one", "2"=>"two"}
>> h.size
=> 2
>> h['1'] = nil
=> nil
>> h.size
=> 2
>> h
=> {"1"=>nil, "2"=>"two"}
>> h.delete('1')
=> nil
>> h.size
=> 1
>> h
=> {"2"=>"two"}
複製程式碼
也可以使用一些表示作為鍵值,也可以不使用 =>
建立雜湊(使用冒號,這和 Objective-C 很相似)
?> h = {:one => 1, :two => 2}
=> {:one=>1, :two=>2}
>> h
=> {:one=>1, :two=>2}
>>
?> h = {one: 1, two: 2}
=> {:one=>1, :two=>2}
>> h
=> {:one=>1, :two=>2}
複製程式碼
常用方法
- 基礎方法
?> a = {"one" => "grac", "two" => "kanil"}
=> {"one"=>"grac", "two"=>"kanil"}
>>
?> a.keys
=> ["one", "two"]
>> a.values
=> ["grac", "kanil"]
>> a.length
=> 2
>> a.size
=> 2
複製程式碼
- has_key?
?> a = {"one" => "grac", "two" => "kanil"}
=> {"one"=>"grac", "two"=>"kanil"}
>> a.has_key? "one"
=> true
複製程式碼
- select
?> a = {"one" => "grac", "two" => "kanil"}
=> {"one"=>"grac", "two"=>"kanil"}
?> a.select { |k, v| k == "one"}
=> {"one"=>"grac"}
>>
?> a.select { |k, v| k == "one" || k == "two"}
=> {"one"=>"grac", "two"=>"kanil"}
複製程式碼
- to_a
?> a = {"one" => "grac", "two" => "kanil"}
=> {"one"=>"grac", "two"=>"kanil"}
?> a.to_a
=> [["one", "grac"], ["two", "kanil"]]
複製程式碼
- 合併兩個
Hash
>> { "one" => "grac" }.merge({ "two" => "kanil" })
=> {"one"=>"grac", "two"=>"kanil"}
複製程式碼
- fetch 和使用
[]
一樣獲取陣列 value,但是如果沒有會raise
錯誤
?> a = {"one" => "grac", "two" => "kanil"}
=> {"one"=>"grac", "two"=>"kanil"}
>> a["three"]
=> nil
>> a.fetch("two")
=> "kanil"
>> a.fetch("three")
KeyError: key not found: "three"
from (irb):7:in `fetch'
from (irb):7
...
複製程式碼
函式關鍵字引數傳遞
Ruby 不支援關鍵字引數,但可以使用 Hash 模擬出來
?> class Article
>> attr_accessor :name, :author, :price
>>
?> def initialize(params = {})
>> @name = params[:name]
>> @author = params[:author]
>> @price = params[:price]
>> end
>> end
=> :initialize
>> a = Article.new(name: "霧都", author: "tom", price: 12.5)
=> #<Article:0x007ffc2189f970 @name="霧都", @author="tom", @price=12.5>
>>
?> a.name
=> "霧都"
複製程式碼
迭代
和陣列很類似
?> hash = {name: "霧都", author: "tom", price: 12.5}
=> {:name=>"霧都", :author=>"tom", :price=>12.5}
>>
?> hash.each {|key, value| puts "#{key} => #{value}"}
name => 霧都
author => tom
price => 12.5
=> {:name=>"霧都", :author=>"tom", :price=>12.5}
複製程式碼