- Rubyのハッシュについて知りたい
- ハッシュのメソッドについて知りたい
配列に合わせて、ハッシュもRubyのシルバー試験で多く出題されたのでまとめました。
生成
ハッシュ式
キーと要素である値とを=>を使った組み合わせで生成する。
a = {"A" => 1, "B" => 2}
p a #>= {"A"=>1, "B"=>2}
p a.class #>= Hash
[]メソッド
キーと値をカンマで区切って列挙する。
a = Hash["A", 1, "B", 2]
p a #>= {"A"=>1, "B"=>2}
newメソッド
キーが存在しない場合の初期値も設定できる。
a = Hash.new
p a #>= {}
p a["A"] #>= nil
# 初期値を設定した場合
b = Hash.new("ない")
p b #>= {}
p b["A"] #>= "ない"
newメソッドは、ブロックで表現することもできる。
a = Hash.new do |hash, key|
hash[key] = nil
end
p a["A"] #>= nil
a = Hash.new do |hash, key|
hash[key] = "ない"
end
p a["A"] #>= "ない"
初期値の再設定
default=メソッドで初期値の再設定が可能。
defaultメソッドやdefault_procメソッドで参照も可能。
a = Hash.new("なし")
p a["A"] #>= "なし"
# 初期値の参照
p a.default #>= "なし"
# 初期値の再設定
a.default = "NONE"
p a.default #>= "NONE
# ブロックの参照
b = Hash.new { |hash, key| hash[key] = "バツ" }
p b["A"] #> "バツ"
p b.default_proc #>= #<Proc:0x007fb1bd90f378@/Users/Documents/test.rb:12>
# default_procでデフォルト値を設定する場合
h = {}
h.default_proc = Proc.new do
"無し"
end
p h["A"] #>= "無し"
取得
[]
指定されたキーに対応する値を返す。
a = {:A => 1, :B => 2, :C => 2}
# キーで取得
p a[:A] #>= 1
# 未設定のキーを設定した場合
p a[:a] #>= nil
keys
ハッシュの全てのキーを取得する。
配列で返却される。
a = {:A => 1, :B => 2, :C => 2}
# キーを取得
p a.keys #>= [:A, :B, :C]
b = {:A => 1}
# キーが1件だったとしても配列で返却
p b.keys #>= [:A]
values
ハッシュの全ての値を取得する。
配列で返却される。
a = {:A => 1, :B => 2, :C => 2}
# 値を取得
p a.values #>= [1, 2, 2]
b = {:A => 1}
# 値が1件だったとしても配列で返却
p b.values #>= [1]
values_at
指定されたキーに対応する値を取得する。
配列で返却される。
a = {:A => 1, :B => 2, :C => 2}
p a.values_at(:A) #>= [1]
# 複数指定も可能
p a.values_at(:A, :B) #>= [1, 2]
# キーが存在しない場合、nilが返却される
p a.values_at(:Z) #>= [nil]
p a.values_at(:A, :Z) #>= [1, nil]
fetch
与えられたキーに対する値を返す。
キーが存在しない場合、第2引数で与えられた値を返す。
第2引数にブロックが与えられている場合は、ブロックを評価した結果を返す。
a = {:A => 1, :B => 2}
p a.fetch(:A) #>=
#p a.fetch(:C) #>= KeyError
p a.fetch(:C, "NO") #>= "NO"
# ブロックで指定した場合
p a.fetch(:C) { |key| key == :C} #>= true
p a.fetch(:E) { |key| key == :C} #>= false
# キーが存在する場合はその値を返却する
p a.fetch(:A) { |key| key == :C} #>= 1
select
キーと値の組み合わせについてブロックを評価して、結果がtrueの組み合わせのハッシュを返却する。
a = {:A => 1, :B => 2}
p a.select{ |key, value| key == :A } #>= {:A=>1}
p a.select{ |key, value| key == :C } #>= {}
fina_all
キーと値の組み合わせについてブロックを評価して、結果がtrueの組み合わせのキーと値の配列を返す。
a = {:A => 1, :B => 2}
p a.find_all{ |key, value| key == :A } #>= [[:A, 1]]
p a.find_all{ |key, value| key == :C } #>= []
変更
[]=
指定されたキーに対応する値を変更する。
破壊的メソッド。
キーが存在しない場合は、指定したキーと値を登録する。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
a[:A] = 99
p a #>= {:A=>99, :B=>2}
a[:C] = "aaa"
p a #>= {:A=>99, :B=>2, :C=>"aaa"}
delete
指定されたキーに対応する値を取り除く。
キーが存在していれば、その値を返す。
破壊的メソッド。
キーが存在しない場合は、nilを返す。
ブロックが与えられていた場合は、ブロックの評価結果を返す。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.delete(:A) #>= 1
p a #>= {:B=>2}
p a.delete(:C) #>= nil
p a.delete(:A) { "none" } #>= "none"
reject
ブロックを評価した結果がtrueになる値を取り除いたハッシュを生成して返す。
元のオブジェクトは変更されない。
!をつけると破壊的メソッドになる。
ブロックした評価がfalseの場合、nilを返す。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.reject{|key, value| key == :A} #>= {:B=>2}
p a #>= {:A=>1, :B=>2}
p a.reject!{|key, value| key == :A} #>= {:B=>2}
p a #>= {:B=>2}
p a.reject!{|key, value| key == :Z} #>= nil
delete_if
ブロックを評価した結果がtrueの値を取り除く。
破壊的メソッド。
評価した結果がfalseの場合、元のハッシュをそのまま返す。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.delete_if{|key, value| key == :A} #>= {:B=>2}
p a #>= {:B=>2}
p a.delete_if{|key, value| key == :Z} #>= {:B=>2}
replace
引数で与えられたハッシュで自分自身を置き換える。
自分自身を置き換えるので、objectIDは変わらない。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.object_id #>= 70206101765140
p a.replace({:C => 3, :D => 4}) #>= {:C=>3, :D=>4}
p a.object_id #>= 70206101765140
shift
ハッシュから先頭のキーと値の組み合わせを1つ取り除き、その組み合わせを配列として返す。
取り除く値がない場合は、nilを返す。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.shift #>= [:A, 1]
p a #> {:B=>2}
p a.shift #>= [:B, 2]
p a #> {}
p a.shift #>= nil
p a #> {}
merge
自分自身と引数で指定されたハッシュを結合(マージ)した新しいハッシュを返す。
デフォルト値は、自分自身の設定が引き継がれる。
ブロックが与えられた場合は、キーと自分自身の値、指定されたハッシュの値が渡され、ブロックの評価結果が新しいハッシュの値となる。
!をつけると破壊的メソッドになる。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.merge({:C =>3, :D => 4}) #>= {:A=>1, :B=>2, :C=>3, :D=>4}
p a #>= {:A=>1, :B=>2}
p a.merge!({:C =>3, :D => 4}) #>= {:A=>1, :B=>2, :C=>3, :D=>4}
p a #>= {:A=>1, :B=>2, :C=>3, :D=>4}
# ブロックを使う場合
# ブロックまで処理がいかない
p a.merge({:E => 5, :F => 6}){|key, self_value, other_value| self_value } #>= {:A=>1, :B=>2, :C=>3, :D=>4, :E=>5, :F=>6}
# キーが被った場合、ブロックに入る
# 以下は、:Aの場合は元の値。それ以外は後から指定した値を使用する。
p a.merge({:A => 9999, :B => 9999}){|key, self_value, other_value| key == :A ? self_value : other_value} #>= {:A=>1, :B=>9999, :C=>3, :D=>4}
update
自分自身と引数で指定されたハッシュを統合する。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.update({:C => 3, :D => 4}) #>= {:A=>1, :B=>2, :C=>3, :D=>4}
p a #>= {:A=>1, :B=>2, :C=>3, :D=>4}
invert
キーと値を逆にしたハッシュを返す。
非破壊的メソッド。
値が重複した場合は、後に登録したキーで上書きされる。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.invert #>= {1=>:A, 2=>:B}
p a #>= {:A=>1, :B=>2}
b = {:A => 1, :B => 2, :C => 1}
p b #>= {:A=>1, :B=>2, :C=>1}
p b.invert #>= {1=>:C, 2=>:B}
p b #>= {:A=>1, :B=>2, :C=>1}
clear
ハッシュを空にする。
a = {:A => 1, :B => 2}
p a #>= {:A=>1, :B=>2}
p a.clear #>= {}
p a #>= {}
調査
length
ハッシュの組み合わせの数を返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.length #>= 3
a.clear
p a.length #>= 0
size
ハッシュの組み合わせの数を返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.size #>= 3
a.clear
p a.size #>= 0
empty?
ハッシュが空であるかどうかを調べる。
空の場合に、trueを返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.empty? #>= false
a.clear
p a.empty? #>= true
include?
ハッシュにキーが存在する場合にtrueを返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.include?(:A) #>= true
p a.include?(:Z) #>= false
# 空の場合
a.clear
p a.include?(:A) #>= false
key?
ハッシュにキーが存在する場合にtrueを返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.key?(:A) #>= true
p a.key?(:Z) #>= false
# 空の場合
a.clear
p a.key?(:A) #>= false
member?
ハッシュにキーが存在する場合にtrueを返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.member?(:A) #>= true
p a.member?(:Z) #>= false
# 空の場合
a.clear
p a.member?(:A) #>= false
has_key?
ハッシュにキーが存在する場合にtrueを返す。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.has_key?(:A) #>= true
p a.has_key?(:Z) #>= false
# 空の場合
a.clear
p a.has_key?(:A) #>= false
has_values?
ハッシュに値が存在する場合に、trueを返す。
a = {:A => 1, :B => 2, :C => 2}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.has_value?(1) #>= true
p a.has_value?(999) #>= false
# 複数の値が存在する場合
p a.has_value?(2) #>= true
# 空の場合
a.clear
p a.has_value?(1) #>= false
value?
ハッシュにキーが存在する場合にtrueを返す。
a = {:A => 1, :B => 2, :C => 2}
p a #>= {:A=>1, :B=>2, :C=>2}
p a.value?(1) #>= true
p a.value?(999) #>= false
# 複数の値が存在する場合
p a.value?(2) #>= true
# 空の場合
a.clear
p a.value?(1) #>= false
繰り返し
each
与えられたブロックにキーと値を渡して評価する。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
a.each { |key, value| p "#{key}の値は、#{value}" }
#>= "Aの値は、1"
#>= "Bの値は、2"
#>= "Cの値は、3"
each_pair
eachと同じ。
与えられたブロックにキーと値を渡して評価する。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
a.each_pair { |key, value| p "#{key}の値は、#{value}" }
#>= "Aの値は、1"
#>= "Bの値は、2"
#>= "Cの値は、3"
each_key
キーをブロックに渡して評価する。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
a.each_key { |key| p "キーの値は、#{key}" }
#>= "キーの値は、A"
#>= "キーの値は、B"
#>= "キーの値は、C"
# こう書いてもvalueの値は取れない
a.each_key { |key, value| p "#{key}の値は、#{value}" }
#>= "Aの値は、"
#>= "Bの値は、"
#>= "Cの値は、"
each_value
値をブロックに渡して評価する。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
a.each_value { |value| p "キーの値は、#{value}" }
#>= "値は、1"
#>= "値は、2"
#>= "値は、3"
# こう書いてもkeyの値は取れない
# 第1引数に値が入るため、変数key=値となる
a.each_value { |key, value| p "#{key}の値は、#{value}" }
#>= "1の値は、"
#>= "2の値は、"
#>= "3の値は、"
ソート
ハッシュをキーと値の組み合わせの配列に変換し、ソートした結果を返す。
ハッシュ自身をソートする訳ではない。
ブロックが与えられた場合には、キーと値の組み合わせの配列が渡される。
a = {:B => 1, :C => 2, :A => 3 , :D => 99}
p a #>= {:B=>1, :C=>2, :A=>3, :D=>99}
p a.sort #>= [[:A, 3], [:B, 1], [:C, 2], [:D, 99]]
p a #>= {:B=>1, :C=>2, :A=>3, :D=>99}
# 値である数値でソート。もともと揃っているから変わり無し。
p a.sort{|a,b| a[1] <=> b[1]} #>= [[:B, 1], [:C, 2], [:A, 3], [:D, 99]]
# 逆順
p a.sort{|a,b| b[1] <=> a[1]} #>= [[:D, 99], [:A, 3], [:C, 2], [:B, 1]]
変換
ハッシュを配列に変換するには、to_aメソッドを使う。
キーと値の組み合わせを配列の配列を生成する。
a = {:A => 1, :B => 2, :C => 3}
p a #>= {:A=>1, :B=>2, :C=>3}
p a.to_a #>= [[:A, 1], [:B, 2], [:C, 3]]
p a #>= {:A=>1, :B=>2, :C=>3}
まとめ
- 生成
- 取得
- 変更
- 調査
- 繰り返し
- ソート
- 変換
上記メソッドについてまとめましたー。
やっぱり色々コード書いて試さないと覚えないですね。。