Help us understand the problem. What is going on with this article?

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

More than 5 years have 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}
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away