LoginSignup
262
268

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-01-06

概要

パーフェクト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}
262
268
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
262
268