例
どうしてもhashのkeyを全てシンボルにしたくなった場合
require 'yaml'
yaml = YAML.load_file("sample.yml")
h1 = Hash[
*yaml["a"].keys.map{|key|
[key.to_sym, yaml["a"][key]]
}.flatten(1)
]
p yaml["a"]
p h1
- sample.yml
a:
b1: c1
b2: c2
b3: c3
b4: c4
実行結果
{"b1"=>"c1", "b2"=>"c2", "b3"=>"c3", "b4"=>"c4"}
{:b1=>"c1", :b2=>"c2", :b3=>"c3", :b4=>"c4"}
ほら、keyがシンボルになっているでしょ!
(今回の例だと、「yaml側でシンボルにしろよ!」って言われる場面なのですが、そこに触れてはダメです。)
なにをしているの?
以下は配列からハッシュを生成する方法の例です。
(2) キーと値のペアの配列からハッシュへalist = [[1,"a"], [2,"b"], [3,["c"]]] p Hash[*alist.flatten(1)] # => {1=>"a", 2=>"b", 3=>["c"]}
というのを使っています。
例に挙げたコードを分解してみる
yamlファイルから読み取る
yaml = YAML.load_file("sample.yml")
p yaml #=> {"a"=>{"b1"=>"c1", "b2"=>"c2", "b3"=>"c3", "b4"=>"c4"}}
- ここは今回のメインではないです
キーをシンボルに変更した配列を作成し、平滑化する
array = yaml["a"].keys.map{|key|
[key.to_sym, yaml["a"][key]]
}
p array #=> [[:b1, "c1"], [:b2, "c2"], [:b3, "c3"], [:b4, "c4"]]
p array.flatten(1) #=> [:b1, "c1", :b2, "c2", :b3, "c3", :b4, "c4"]
平滑化の再帰の深さを整数で指定します。
nil を指定した場合、再 帰の深さの制限無しに平滑化します。
整数以外のオブジェクトを指定した場合は to_int メソッドによる暗 黙の型変換を試みます。
- keys.mapの中の処理を変えれば、hashのkeyだけではなくて、valueも自由自在ですね!
キーと値のペアの配列からハッシュを作る
# array #=> [[:b1, "c1"], [:b2, "c2"], [:b3, "c3"], [:b4, "c4"]]
h1 = Hash[*array.flatten(1)]
p h1 #=> {:b1=>"c1", :b2=>"c2", :b3=>"c3", :b4=>"c4"}
まとめ
- hashを素にarrayを作ってhashにすれば、一応出来る
配列からハッシュが作れるとか知らなかった僕なのでした(笑
今回、例に挙げたコードは実用性が無いな〜。
何に使えるんだろ?
用途、募集中です(苦笑
追記
追記1
yuku_tさんにコメントで教えて頂きました!
ちなみにRailsにはHash#symbolize_keysとHash#symbolize_keys!っていう、ほぼ同じことをしてくれるメソッドがあります :)
rails / activesupportdef symbolize_keys! keys.each do |key| self[(key.to_sym rescue key) || key] = delete(key) end self end
ぉぉ〜。 keyをシンボル化したいだけなら、こっちですな!!
追記2
hilohiroさんにコメントで教えて頂きました!
require "yaml"
yaml = YAML.load_file("sample.yml")
h1 = Hash[
yaml["a"].map{|key, value|
[key.to_sym, value]
}
]
Hash#mapってarrayが返るんですね!
知りませんでした(=w=;
少しずつ、シンプルになる感じがいいですね〜(=w=