each...or else――Rubyで空のコレクションをエレガントに処理する方法
Rubyのeachは非常に便利なメソッドですが、ひとつ悩ましい問題があります。コレクションが空だった場合はどうなるのでしょうか?
[].eachを呼び出しても何も起こらず、単に[]が返されるだけです。それが望ましい動作であるケースもあります。しかし多くの場合、特にUIを構築している際には、空のリストを特別に扱いたくなるものです。たとえば私なら、データがひとつもないときには別のメッセージを表示したいと考えます。
ところが[].eachは[]を返すのであってnilではないため、次のような書き方をするしかありません。
<% if @users.empty? -%>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
<% else -%>
<% @users.each do |user| -%>
<p><%= user.name %></p>
<% end -%>
<% end -%>
これでも動作しますが、どこかぎこちなく感じます。むしろ「このコレクションの各要素にこの処理を行う。ただし中身が空なら、まったく別の処理をする」と言いたいところです。つまり、「or else(さもなくば)」付きのeachが欲しいのです。
Railsビューでのコレクション描画
ビューの中であれば、Railsが力になってくれます。Railsはオブジェクトのコレクション描画がとても得意です。
<%= render @users %>
<p><%= user.name %></p>
renderに@usersを渡すと、@users内のユーザーごとに_user.html.erbが一度ずつ描画されます。わざわざeachを書く必要はありません。
さらに嬉しいことに、@usersが空の場合、renderはnilを返してくれます。まさに望みどおりの挙動です!したがって、次のように書けば、最初のバージョンと同じ出力が得られます。
<%= render(@users) || render('empty') %>
<p><%= user.name %></p>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
Railsの規約さえ理解していれば、ずっと直接的で読みやすいコードになります。
ビューの外ではどうする?
Railsの流儀に従えば、コレクションを渡したrenderは、オブジェクト群を高速かつ強力に描画できる手段となります。
しかし、項目ごとにパーシャルを追加で用意したくないこともあるでしょう。あるいはrenderではデザイン要件を満たせないかもしれません。そもそもビューの中にいないケースもあります。
今のところ私が見つけた最良の解決策は、presenceです。
list.presenceは、次のコードと同じ意味になります。
if list.present?
list
else
nil
end
つまり、リストに何か入っていればそのリストが返り、空ならnilが返るということです。
presenceを使えば、次のように書けます。
@users.each do |user|
puts user.name
end.presence || puts("You don't have any users.")
@usersにユーザーがいれば各名前が出力され、いなければ「You don't have any users.」と表示されます。
とはいえ、presenceなしで書ければそれに越したことはありません。これはハックであり、実際にハックだからです。もし言語側でサポートされているなら、次のような書き方のほうが自然でしょう。
@users.each do |user|
puts user.name
end || puts("You don't have any users.")
あるいはSmalltalk風に、こんな感じでしょうか。
@users.each(if_empty: lambda { puts "You don't have any users." }) do |user|
puts user.name
end
さらには(驚くなかれ)、こんな構文も想像できます。
for user in @users
puts user.name
else
puts "You don't have any users."
end
ただ現時点では、私はpresenceを使うか、素朴なif blank?; else eachパターンを採用することがほとんどです。
あなたはどの方法が良いと思いますか? 空のリストはどのように処理していますか? もっと良い方法を見つけた経験があれば、ぜひ教えてください!
-
JavaScriptの条件分岐とは?if文・else文・else if文の使い方を解説
JavaScriptには、条件に応じて処理を切り替えるための「条件分岐(条件文)」が用意されています。条件式が真(true)か偽(false)かを評価することで、実行するコードを制御できます。代表的な条件文は次の3種類です。 if文 − 指定した条件が満たされた場合にのみ、ifブロック内のコードを実行します。最も基本的な条件分岐です。 if…else文 − 条件が真の場合と偽の場合で、それぞれ異なる処理を実行したいときに使います。2つのケースを切り替えるのに適しています。 if…else if…else文 − 3つ以上の条件を扱いたい場合に使用します。条件を上から順に評価し、最初に一致したブ
-
SQL ServerのIF...ELSE文とは?基本構文と実践例をわかりやすく解説
他のプログラミング言語と同様に、SQL Serverでも条件分岐を行うためのIF...ELSEコマンドが用意されています。本記事では、IF...ELSE文の構文の使い方を、わかりやすい具体例とともに詳しく解説します。 概要 SQL ServerにおけるIF...ELSE文は、条件に応じて処理を分岐させるために使用されるステートメントです。条件がTRUE(真)と評価された場合は一方的な処理を実行し、FALSE(偽)と評価された場合には別の処理を実行します。 IF...ELSE文の構文 SQL ServerでIF...ELSEによる分岐処理を行うには、以下の構文に従って記述します。 IF 条件式{