1. Hash 連想配列
連想配列ってのは、この手の言語では必ず出現する便利な奴ですな。
連想配列に関しては、以下に詳しく述べられています。
「Ruby 2.5.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Hash クラス 」
2. 初期化
要素つきの初期化を行うには、まず、次の4つのいずれか。
この4つは同じ意味を持ちます。
hash = Hash[ 'foo' => 'bar', 'hoge' => 'fuga' ]
hash = Hash[ :foo => 'bar', :hoge => 'fuga' ]
hash = { 'foo' => 'bar', 'hoge' => 'fuga' }
hash = { :foo => 'bar', :hoge => 'fuga' }
「Hash.new」で要素をいれることができるようですが、使い方が難しくてよくわかりません。
: と '' の使い分けはまだわかっていません。
キーと値を区別するには : の方がいいのかしらん。
メンバなしの初期化は、次の3つのいずれか。
hash = {}
hash = Hash[]
hash = Hash.new
3. 追加
要素を追加するには、以下のいずれかの構文を使います。
hash[:foo] = 'bar'
hash['hoge'] = 'fuga'
4. 全件アクセス
全件アクセスするには each(キーと値を取得)、each_key(キーを取得)、each_value(値を取得)を使います。
hash = { :foo => 'bar', :hoge => 'fuga' }
# |(パイプライン)で囲む
hash.each { | key, value |
puts "[#{__LINE__}] key = #{key} value = #{value}"
}
hash.each_key { | key |
puts("[#{__LINE__}] key = #{key} ")
}
hash.each_value { | value |
puts("[#{__LINE__}] value = #{value}")
}
# do ~ end で囲む
hash.each do | key, value |
puts "[#{__LINE__}] key = #{key} value = #{value}"
end
hash.each_key do | key |
puts("[#{__LINE__}] key = #{key} ")
end
hash.each_value do | value |
puts("[#{__LINE__}] value = #{value}")
end
値となる変数を囲んだ |値| の後ろの |(パイプライン)までは、Array のときと同じく、改行不可です。
その後の } までは1行で書いてもいいし、改行してもいいようです。
また、ループを囲む書式として |(パイプライン)で囲む書式と do ~ end で囲む書式と両方とも文法として成り立つようですし、同じ結果になります。
これを実行すると以下のような結果となります。
[6] key = foo value = bar
[6] key = hoge value = fuga
[10] key = foo
[10] key = hoge
[14] value = bar
[14] value = fuga
[20] key = foo value = bar
[20] key = hoge value = fuga
[24] key = foo
[24] key = hoge
[28] value = bar
[28] value = fuga
同じ結果を得られる each_pair というのがあるようですが、処理が全く同じなら each だけ知ってればいいかな。
each_pair は each_key や each_value との対比であるのでしょうね。
5. キーを持っているか has_key?
has_key? も include? も key?(key) も member?(key) も全部同じ。
has_key?(key)
include?(key)
key?(key)
member?(key)
どれも同じ形式で bool 値を返してきます。
#!/usr/bin/env ruby
hash = { :foo => 'fufufu' }
puts('hash.has_key?(:foo) = ['"#{hash.has_key?(:foo)}"']')
puts('hash.has_key?(:bar) = ['"#{hash.has_key?(:bar)}"']')
puts('hash.include?(:foo) = ['"#{hash.include?(:foo)}"']')
puts('hash.include?(:bar) = ['"#{hash.include?(:bar)}"']')
puts('hash.key?(:foo) = ['"#{hash.key?(:foo)}"']')
puts('hash.key?(:bar) = ['"#{hash.key?(:bar)}"']')
puts('hash.member?(:foo) = ['"#{hash.member?(:foo)}"']')
puts('hash.member?(:bar) = ['"#{hash.member?(:bar)}"']')
上記のコードを実行すると、下記の結果になります、
hash.has_key?(:foo) = [true]
hash.has_key?(:bar) = [false]
hash.include?(:foo) = [true]
hash.include?(:bar) = [false]
hash.key?(:foo) = [true]
hash.key?(:bar) = [false]
hash.member?(:foo) = [true]
hash.member?(:bar) = [false]
6. 削除
ハッシュ変数.delete(キー) でキーを削除することができます。
hash1 = { :foo => 'bar', :hoge => 'fuga', :baz => 'qux' }
hash2 = { :foo => 'bar', :hoge => 'fuga', :baz => 'qux' }
puts "[#{__LINE__}] hash1 = #{hash1}"
puts "[#{__LINE__}] hash2 = #{hash2}"
hash1.delete(:hoge)
puts "[#{__LINE__}] hash1 = #{hash1}"
hash2.each do | key, value |
if (key[0] == 'h')
hash2.delete(key)
end
end
puts "[#{__LINE__}] hash2 = #{hash2}"
上記のソースを書いて実行すると下記の結果が得られます。
[4] hash1 = {:foo=>"bar", :hoge=>"fuga", :baz=>"qux"}
[5] hash2 = {:foo=>"bar", :hoge=>"fuga", :baz=>"qux"}
[9] hash1 = {:foo=>"bar", :baz=>"qux"}
[17] hash2 = {:foo=>"bar", :baz=>"qux"}
「hash2」の例の場合、ループ内でキーを削除するので例外となるかも?と思ったのですが、正常に動作するようです。