すっかり寒くなりましたね。
みなさん、each使ってますか??便利で利用シーンの多いこの子ですが、どんな構造のデータに対して使うべきかを考えなければ、読みにくく、拡張性の低いものになってしまいます。今回の記事では、僕のeachに突っ込むデータの変遷を晒し上げ、「こんなものをeachで回すんじゃあないよ」と言いたくなるようなアンチパターンの配列(ハッシュ)を紹介していきます。
今回出力したい内容は以下の通り。
Tom(年齢:23歳、身長:170cm、出身国:Canada)
Mika(年齢:27歳、身長:150cm、出身国:Japan)
Brown(年齢:23歳、身長:170cm、出身国:Brazil)
それではeachで回してみましょう!!
フェーズ1:配列しか勝たん
person_info_array = [['Tom', 23, 170, 'Canada'],
['Mika', 27, 150, 'Japan'],
['Brown', 19, 190, 'Brazil']]
person_info_array.each do |person_info|
puts "#{person_info[0]}(年齢:#{person_info[1]}、身長:#{person_info[2]}、出身国:#{person_info[3]})"
end
当初僕は、「eachで回すなら配列一択でしょ!!」と思っていたのでこんな配列を作っていました。配列を見てもぱっと見どの情報が何を示すのかわからないですし、年齢の前に趣味を入れたい!となった時には
person_info_array = [['Tom', 'baseball', 23, 170, 'Canada'],
['Mika', 'hunting', 27, 150, 'Japan'],
['Brown', 'cooking', 19, 190, 'Brazil']]
person_info_array.each do |person_info|
puts "#{person_info[0]}(趣味:#{person_info[1]}、年齢:#{person_info[2]}、身長:#{person_info[3]}、出身国:#{person_info[4]})"
end
このように他の順番も変更する必要があります。これはあまりイケてないですね。。
フェーズ2:え、配列もハッシュも使えますけど?
person_info_array = ['Tom' => {age: 23, tall: 170, country: 'Canada'},
'Mika' => {age: 27, tall: 150, country: 'Japan'},
'Brown' => {age: 19, tall: 190, country: 'Brazil'}]
person_info_array.each do |person_info|
person_info.each do |name, profile|
puts "#{name}(年齢:#{profile[:age]}、身長:#{profile[:tall]}、出身国:#{profile[:country]})"
end
end
少し学習が進み、ハッシュやシンボルの存在を知った僕は色々使ってみたくなってこんなことをしていました。ハッシュを用いることでデータの関連がわかりやすくなりました。この配列であれば、先ほどのように趣味を入れるのも楽々です。
person_info_array = ['Tom' => {age: 23, tall: 170, country: 'Canada', hobby: 'baseball'},
'Mika' => {age: 27, tall: 150, country: 'Japan', hobby: 'hunting'},
'Brown' => {age: 19, tall: 190, country: 'Brazil', hobby: 'cooking'}]
person_info_array.each do |person_info|
person_info.each do |name, profile|
puts "#{name}(趣味:#{profile[:hobby]}、年齢:#{profile[:age]}、身長:#{profile[:tall]}、出身国:#{profile[:country]})"
end
end
しかしながら、eachがネストしてしまっています。惜しい。。
フェーズ3:今ココ←
person_info_hash = {'Tom' => {age: 23, tall: 170, country: 'Canada'},
'Mika' => {age: 27, tall: 150, country: 'Japan'},
'Brown' => {age: 19, tall: 190, country: 'Brazil'}}
person_info_hash.each do |name, profile|
puts "#{name}(年齢:#{profile[:age]}、身長:#{profile[:tall]}、出身国:#{profile[:country]})"
end
配列をハッシュに変えることでネストがなくなり、だいぶマシになりました。
まとめ
いかがでしたでしょうか。
配列、ハッシュをeachで回す際には以下のそれぞれの特性を考慮して使いたいですね。
配列:
- 連続した要素を順番に処理したい場合
- インデックスや要素の順序に意味があるデータを扱う場合
ハッシュ:
- キーと値のペアを順番に処理したい場合
- キーと値の関連性が重要なデータを扱う場合
- データの構造がキーとそれに関連する情報を持っている場合
「〇〇さん(名前):プロフィール(年齢、身長、出身国)」という情報の関連があること、順序が重要な意味を持つわけではないことを考えると、今回は名前の単位でハッシュにまとめる方法が良いなという結論に至りました。
このような試行錯誤を重ねることで、より良い方法や思考にたどり着けるのって快感ですよね!
最後まで読んでいただき、ありがとうございました!