Just do IT

思うは招く

Ruby基礎問題100本ノック#18 文字列をハッシュに入れる

お題

空白、タブ、改行で区切られた以下の文字列を、ハッシュに変換するメソッドstr_to_hashを定義せよ。

# こんな文字列を
”blue 青 white 白\nred 赤”

# こんなふうにしてくれよぉ
=> {"blue"=>"青", "white"=>"白", "red"=>"赤"}

なお、空白、タブ、改行を表す正規表現はこちら。

/\s+/

引用:「たのしいRuby 第6版」P.340より

回答

def str_to_hash(str)
  hash = Hash.new(0)
  ary = str.split(/\s+/)
  while key = ary.shift
    value = ary.shift
    hash[key] = value
  end
  hash
end
str = %Q(blue 青 white 白\nred 赤)
puts str_to_hash(str)
=> {"blue"=>"", "white"=>"", "red"=>""}

説明

まずハッシュを用意する。このとき、hash = {}ではだめ。Hash.new(0)で値に0を入れて初期化しないと、nilが返ってエラーが出る。

hash = Hash.new(0)

次に、文字列を正規表現で区切って配列に入れる。

ary = str.split(/\s+/)
=> ["blue", "", "white", "", "red", ""]

whileで繰り返す。 ary.shiftで配列の先頭要素をひとつずつ取り出す。

  while key = ary.shift
    value = ary.shift
    hash[key] = value
  end

最後にreturnの意味でhashを記述する。

hash

文字列は%Qで作っている。

str = %Q(blue 青 white 白\nred 赤)

k-koh.hatenablog.com

学び

「Array#shiftがこう使えるのか」と勉強になった。

  while key = ary.shift
    value = ary.shift
    hash[key] = value
  end

このwhile文では、変数keyへの代入と、判定を同時におこなっている。 ary.shiftの戻り値がkeyに代入される。

別の例題で考えてみる。

こんな配列があったとする。

animals = ["elephant", "dog", "cat", "mouse"]

ハッシュを初期化し、今回の例題と同じことをしてみる。

hash = Hash.new(0)
while key = animals.shift
    value = animals.shift
    hash[key] = value
end
hash
=> {"elephant"=>"dog", "cat"=>"mouse"}

つまり、key = animals.shiftでは、配列の先頭であるelephantがkeyに代入され、次の要素であるdogがvalueに代入される。これらがキーと値のペアとなる。

だから、こうなる。

{"elephant"=>"dog", "cat"=>"mouse"}

シンプルだし簡単。

ref.xaio.jp