🐘

【Rails】配列の要素をキーにしてナンバリングしたハッシュを生成する

2024/02/08に公開

概要

現場で、Ruby の配列の要素順にナンバリングされたハッシュを作成するという場面に遭遇し、
スマートな書き方を学んだので備忘録。

# こういう配列を
["あああ", "いいい", "ううう"]

# こういうハッシュにする方法
{"あああ"=>0, "いいい"=>1, "ううう"=>2}

環境

ruby '3.1.2'
rails '7.0.8'

結論

index_withwith_index を使います。

["あああ", "いいい", "ううう"].index_with.with_index{ |_item, i| i }
=> {"あああ"=>0, "いいい"=>1, "ううう"=>2}

# 1から始めたければこう
["あああ", "いいい", "ううう"].index_with.with_index(1){ |_item, i| i }
=> {"あああ"=>1, "いいい"=>2, "ううう"=>3}

index_with と with_index

index_with

index_with は配列の各要素をキーとし、ブロックの最終評価をバリューにして新しいハッシュを生成します。

["あああ", "いいい", "ううう"].index_with{ |item| "valueは#{item}" }
=> {"あああ"=>"valueはあああ", "いいい"=>"valueはいいい", "ううう"=>"valueはううう"}

with_index

with_index は、Enumerator インスタンスに対して使用できるメソッドになります。
ブロック引数の第二引数に、各要素の要素番号が代入されます。

each と一緒に使われているのをよく見ますね。

["あああ", "いいい", "ううう"].each.with_index{ |item, i| p "#{item}の要素番号は#{i}"}
"あああの要素番号は0"
"いいいの要素番号は1"
"うううの要素番号は2"
=> ["あああ", "いいい", "ううう"]

ただし、index_with は Rails でしか使えません。

おまけ

index_by を使うと、キーでナンバリングできます。

["あああ", "いいい", "ううう"].index_by.with_index{|_item, i| i}
=> {0=>"あああ", 1=>"いいい", 2=>"ううう"}

Enumerable のチェーンの挙動が難しいなぁ...。

Discussion