9
9

More than 5 years have passed since last update.

Rubyでhashの要素を処理して、hashを返す

Last updated at Posted at 2013-06-03

どうしても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側でシンボルにしろよ!」って言われる場面なのですが、そこに触れてはダメです。)

なにをしているの?

singleton method Hash.[]

以下は配列からハッシュを生成する方法の例です。
(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 / activesupport

  def 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=

9
9
4

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
9
9