【Ruby】ハッシュメソッドまとめ

  • 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}

まとめ

  • 生成
  • 取得
  • 変更
  • 調査
  • 繰り返し
  • ソート
  • 変換

上記メソッドについてまとめましたー。

やっぱり色々コード書いて試さないと覚えないですね。。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です