Ruby には each_with_object
メソッドがある。
名前のとおり、each
メソッドを使えて、空の配列やハッシュなどを引数に渡してそれをオブジェクトとして処理できる。最終的には引数に渡した配列やハッシュを返す。
配列の場合
each_with_object([])
と引数に空配列を渡すことで、|num, ary|
のようにブロックの第二引数に空配列を渡すことができる。
result = (1..5).each_with_object([]) do |num, ary| p num p ary end p result 1 [] 2 [] 3 [] 4 [] 5 []
渡した空配列に、ブロックの第一引数の要素を<<
していく。
result = (1..5).each_with_object([]) do |num, ary| p ary << num * 5 end p result = [5] [5, 10] [5, 10, 15] [5, 10, 15, 20] [5, 10, 15, 20, 25] => [5, 10, 15, 20, 25]
num
に5をかけた数値を[]
に代入している。
ハッシュの場合
each_with_object({})
のように、引数にハッシュを渡すこともできる。
hash = { a: "テイタム", b: "ブラウン", c: "ウォーカー" } result = hash.each_with_object({}) do |item, new_hash| p item p new_hash end p result [:a, "テイタム"] {} [:b, "ブラウン"] {} [:c, "ウォーカー"] {}
この場合、ブロックの第一引数にはハッシュの要素が配列の形で入っている。
ハッシュのkeyやvalueを使う場合には、ブロックの第一引数に(key, value)
と書くことでどちらも扱うことができる。
hash = { a: "テイタム", b: "ブラウン", c: "ウォーカー" } result = hash.each_with_object({}) do |(key, value), new_hash| p key p value p new_hash end p result :a "テイタム" {} :b "ブラウン" {} :c "ウォーカー" {}
each_with_object({})
で引数に入れているハッシュを使ってみると、こうなる。
result = hash.each_with_object({}) do |(key, value), new_hash| new_hash["#{key}"] = "#{value}だよん" end p result {"a"=>"テイタムだよん", "b"=>"ブラウンだよん", "c"=>"ウォーカーだよん"}
ここでは、new_hash
の各keyとして、もともとはシンボルだったkeyを文字列にして、その要素にvalueを代入している。
もともとシンボルだったkeyをそのままシンボルとして使うなら、こうなる。
hash = { a: "テイタム", b: "ブラウン", c: "ウォーカー" } result = hash.each_with_object({}) do |(key, value), new_hash| new_hash[key] = "#{value}だよん" end p result {:a=>"テイタムだよん", :b=>"ブラウンだよん", :c=>"ウォーカーだよん"}
配列とハッシュの場合
レシーバに配列、引数にハッシュを渡すこともできる。
ary = [1, 2, 3] hash = ary.each_with_object({}) do |value, new_hash| new_hash[value] = "hoge" end p hash {1=>"hoge", 2=>"hoge", 3=>"hoge"}