[Ruby] 便利な組み込みクラスのメソッド達(Hash編)

More than 1 year has passed since last update.

概要

パーフェクトRubyを読んでいて便利だと思ったもの一覧です。

Enumerable編
http://qiita.com/kidachi_/items/a00558cfb0a6a3e23f4b
Array編
http://qiita.com/kidachi_/items/e9cb26c4e6cb36b70a1c
String編
http://qiita.com/kidachi_/items/7b355eb355b2d1390cf5

繰り返し処理

each

ハッシュのキーと値を繰り返す。

> hash = { Ruby: 1, Python: 2, Java: 3 }
=> {:Ruby=>1, :Python=>2, :Java=>3}

> hash.each do |key, value|
>   p "#{key}: #{value}"
> end
"Ruby: 1"
"Python: 2"
"Java: 3"
=> {:Ruby=>1, :Python=>2, :Java=>3}

each_key

ハッシュのキーだけ繰り返す。

> hash.each_key do |key|
>   p "#{key}"
> end
"Ruby"
"Python"
"Java"
=> {:Ruby=>1, :Python=>2, :Java=>3}

each_value

ハッシュの値だけ繰り返す。

> hash.each_value do |value|
>   p "#{value}"
> end
"1"
"2"
"3"
=> {:Ruby=>1, :Python=>2, :Java=>3}

マージ

merge

複数のハッシュを1つにまとめる。
キーが重複している場合は、引数として渡された方のハッシュの値で上書きされる。

> hash1 = { Ruby: 1, Python: 2}
> hash2 = { Java: 3, Python: 4}
> hash1.merge(hash2)
=> {:Ruby=>1, :Python=>4, :Java=>3}

キーと値の入れ替え

invert

キーと値を入れ替えた新しいハッシュを生成する。

{Ruby: 1, Python: 2}.invert
=> {1=>:Ruby, 2=>:Python}

# 入れ替えの結果キーが重複した場合は、片方の値が消滅する。
> {Java: 3, Ruby: 3}.invert
=> {3=>:Ruby}

キーや値の存在確認

has_key?, has_value?

キーや値が存在するかどうかチェックする。

> hash = {Ruby: nil}
=> {:Ruby=>nil}

# 存在するキーでも存在しないキーもどちらもnilを返す
> hash[:Ruby]
=> nil
> hash[:Python]
=> nil

# has_key?で区別する。
> hash.has_key?(:Ruby)
=> true
> hash.has_key?(:Python)
=> false

# 値の存在チェックしたい場合はhas_value?を用いる。
> hash.has_value?(nil)
=> true
> hash.has_value?(1)
=> false

キーや値の取得

keys, values

キーや値を配列で取得する。

> hash = {Ruby: 1, Python: 2, Java: 3}
> hash.keys
=> [:Ruby, :Python, :Java]
> hash.values
=> [1, 2, 3]

# 値からキーを取得するにはHash#key
> hash.key(1)
=> :Ruby
# キーから値を取得するにはHash#values_at
> hash.values_at(:Ruby, :Python)
=> [1, 2]

デフォルト値

デフォルト値の設定

存在しないキーを呼んだ時に返す値を設定。

> has_default = Hash.new('We love Ruby!')
=> {}
> has_default[:aaaa]
=> "We love Ruby!"

デフォルト値はブロックで定義することも可能。
ブロックの引数には、「ハッシュ自身」と「参照されたキー」が渡される。

> has_default = Hash.new { |hash, key| "I (#{hash}) don't have #{key}!" }
=> {}
> has_default[:Ruby]
=> "I ({}) don't have Ruby!"
> has_default[:Python]
=> "I ({}) don't have Python!"

> has_default[:Ruby] = 1
=> 1
> has_default[:Python]
=> "I ({:Ruby=>1}) don't have Python!"

fetch

指定したキーに値が存在しなかった場合の戻り値を指定できる。

> hash = {Ruby: 1, Python: 2}
> hash.fetch(:Java, "No key!")
=> "No key!"
# 値が存在するキーならば通常通り値を返却。
> hash.fetch(:Ruby, "No key!")
=> 1

# ブロックによる指定も可能
> hash.fetch(:Java) {|key| "I don't have #{key}!"}
=> "I don't have Java!"

ハッシュの変換

ハッシュから配列へ

to_aで二次元配列へ変換する。

> hash = {Ruby: 1, Python: 2}
> arr = hash.to_a
=> [[:Ruby, 1], [:Python, 2]]

# 二次元配列にはassocでアクセス可能
> arr.assoc(:Ruby)
=> [:Ruby, 1]

配列からハッシュへ

偶数個の配列をハッシュに渡すパターン

> arr = ["Ruby", 1, "Python", 2]
> Hash[*arr]
=> {"Ruby"=>1, "Python"=>2}

# 奇数個の場合は不可
> arr = ["Ruby", 1, "Python", 2, "Java"]
=> ["Ruby", 1, "Python", 2, "Java"]
> Hash[*arr]
ArgumentError: odd number of arguments for Hash

二次元配列をハッシュに渡すパターン

> arr = [[:Ruby, 1], [:Python, 2]]
=> [[:Ruby, 1], [:Python, 2]]
> Hash[arr]
=> {:Ruby=>1, :Python=>2}