🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

2回答

701閲覧

rails 0とnilを判別したい

hurousyotoku500

総合スコア27

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/11/26 07:29

編集2020/11/26 08:18

railsにて条件分岐をさせているのですが、下記のaという配列はコード2個目の通り、whereで絞り込んでおり、中身があったりなかったりします。ただ、aには0も入ることがあるため、0とnilは区別し、nil(配列の中身がカラ)だけを検出したい。

<% @thru_1h_start.zip(@thru_10h_start).each do|a,b| %> <% case %> <% when a.nil? %>     ・・・
#変数aの内容 @thru_1h_start = Score.where(created_at: play_date.created_at.in_time_zone.all_day).where(course: params[:course]).where(hole_number: 1..9).where("hole_score is NULL").group(:round_id).minimum(:hole_number) @thru_10h_start = Score.where(created_at: play_date.created_at.in_time_zone.all_day).where(course: params[:course]).where(hole_number: 10..18).where("hole_score is NULL").group(:round_id).minimum(:hole_number)

試してみたこと

.any?や.empty?も試してみましたが、.nil?と結果はかわりませんでした。

実現したいこと

配列の中身がカラだったら、when文でtrueとしたい。

宜しくお願い致します。

追記

下記のリンクをみると、条件にマッチしないと、空の配列ではないと書いてありました。
イメージ説明
https://qiita.com/nakayuu07/items/3d5e2f8784b6f18186f2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/11/26 07:46

念のため、「0も入る」とはどういう状態でしょうか
hurousyotoku500

2020/11/26 07:48

ゴルフのスコアなので、PARだと0を入れます。
asm

2020/11/26 08:05

@thru_1h_startおよび@thru_10h_startはどのようなデータでしょうか? #inspectや#to_jsonで文字列化(シリアライズ)できると思いますので、具体的にうまく行かない例をください。
hurousyotoku500

2020/11/26 08:43 編集

<% @thru_1h_start.each do |key, value| %> <p>key: <%= key %></p> <p>value: <%= value %><br></p> <% end %> <% @thru_10h_start.each do |key, value| %> <p>key: <%= key %></p> <p>value: <%= value %><br></p> <% end %> 実行結果 key: 683bc2ab3f8ece9d value: 1 key: 2656bd31891aaf04 value: 3 key: 683bc2ab3f8ece9d value: 18 key: 2656bd31891aaf04 value: 10 key: hoge value: 11
hurousyotoku500

2020/11/26 08:43 編集

@thru_1h_startの3つめ(key: hoge)が.where("hole_score is NULL")に対し、全てNULLではないので、配列には何も入らない状態です。
guest

回答2

0

配列の中身がカラだったら、when文でtrueとしたい。

Ruby

1p [].empty? #=> true 2p [1, 2, 3].empty? #=> false 3p [0].empty? #=> false

実行結果:https://paiza.io/projects/ywocFN_SSjiw7-xzBn4cXA?language=ruby
emptyメソッド:https://docs.ruby-lang.org/ja/latest/method/Array/i/empty=3f.html

投稿2020/11/26 08:00

編集2020/11/26 08:02
no1knows

総合スコア3365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hurousyotoku500

2020/11/26 08:25

``` <% when a[1]. empty? %> ``` としてみましたが、結果は変わりませんでした。
no1knows

2020/11/26 08:30

「配列の中身がカラならtrueとしたい」ということで回答したのですが、別の質問でしょうか?
guest

0

それぞれのデータは以下のような配列でしょうか?

ruby

1@thru_1h_start = [["683bc2ab3f8ece9d",1], ["2656bd31891aaf04", 3]] 2@thru_10h_start = [["683bc2ab3f8ece9d", 18], ["2656bd31891aaf04", 10], ["hoge", 11]]

この場合Array#zipによって合成することはできません。

ruby

1@thru_1h_start.zip(@thru_10h_start) 2#=> [ 3# [["683bc2ab3f8ece9d", 1], ["683bc2ab3f8ece9d", 18]], 4# [["2656bd31891aaf04", 3], ["2656bd31891aaf04", 10]] 5# ]

一度Hashに変換した後にmergeやvalues_atを用いるのがよいかと思います。

ruby

1ha = Hash[@thru_1h_start] 2hb = Hash[@thru_10h_start] 3keys = ha.keys | hb.keys 4values_a = ha.values_at(*keys) 5values_b = hb.values_at(*keys) 6keys.zip(values_a, values_b) do |key, a, b| 7...

「上から判定する」という事に注意して
if a && a.between?(1,18) && b == 10
などとする必要があります。
が、無駄に長くなるのでsafe navigation operatorを用いて

erb

1<span> 2<% if a.nil? && b.nil? %>Finish 3<% elsif a.nil? && b&.between?(11,18) %>アウトスタートで、インプレイ中 <%= b - 1 %> 4<% elsif a.nil? && b == 10 %>アウトスタートで、アウト終了 <%= a %> 5<% elsif a == 1 && b.nil? %>インスタートで、イン終了 <%= a - 1 %> 6<% elsif a == 1 && b&.between?(11,18) %>インスタートで、インプレイ中 <%= b - 1 %> 7<% elsif a&.between?(2,9) && b == 10 %>アウトスタートで、アウトプレイ中 <%= a - 1 %> 8<% elsif a&.between?(1,9) && b.nil? %>インスタートで、アウトプレイ中 <%= a - 1 %> 9<% else %>なんか変なスコアのいれ方です 10<% end %></span><br>

などとするとよいでしょう。

ただし、これは見やすいのはいいのですが何度か同じ判定をしているのが非効率で気になりますね。


パターンマッチを用いた場合は

erb

1<span> 2<% case [a, b] 3<% in [nil,nil] %>Finish 4<% in [nil, 10] %>アウトスタートで、アウト終了 <%= a %> 5<% in [1, nil] %>インスタートで、イン終了 <%= a - 1 %> 6<% in [nil, 11..18 => hole] %>アウトスタートで、インプレイ中 <%= hole - 1 %> 7<% in [1, 11..18 => hole] %>インスタートで、インプレイ中 <%= hole - 1 %> 8<% in [2..9 => hole, 10] %>アウトスタートで、アウトプレイ中 <%= hole - 1 %> 9<% in [1..9 => hole, nil] %>インスタートで、アウトプレイ中 <%= hole - 1 %> 10<% else %>なんか変なスコアのいれ方です 11<% end %></span><br>

等も可能ですが、2.7時点ですと警告が出るなど常用は難しいです。

投稿2020/11/26 10:24

編集2020/11/26 23:00
asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hurousyotoku500

2020/11/26 12:16

ご回答ありがとうございます。 下記のように書き直してみましたが、undefined method `between?' for nil:NilClassというエラーを吐いており、まだNilなのでしょうか。 <% ha = Hash[@thru_1h_start] %> <% hb = Hash[@thru_10h_start] %> <% keys = ha.keys | hb.keys %> <% values_a = ha.values_at(*keys) %> <% values_b = hb.values %> <% keys.zip(values_a, values_b) do |key, a, b| %> <% case %> <% when a.between?(2,9) && b == 10 %> <span>アウトスタートで、アウトプレイ中 <%= a - 1 %></span><br> <% when a.empty? && b == 10 %> <span>アウトスタートで、アウト終了 <%= a %></span><br> <% when a.empty? && b.between?(11,18) %> <span>アウトスタートで、インプレイ中 <%= b - 1 %></span><br> <% when a == 1 && b.between?(11,18) %> <span>インスタートで、インプレイ中 <%= b - 1 %></span><br> <% when a == 1 && b.empty? %> <span>インスタートで、イン終了 <%= a - 1 %></span><br> <% when a.between?(1,9) && b.empty? %> <span>インスタートで、アウトプレイ中 <%= a - 1 %></span><br> <% when a.empty? && b.empty? %> <span>Finish</span><br> <% else %> <span>なんか変なスコアのいれ方です</span><br> <% end %> <% end %>
asm

2020/11/26 12:36

empy?ではなくnil?を用いてください。 またcase-whenは上から判定することにも注意が必要です。 (パターンマッチ使えばいい気もしますがRuby2.7現在実験的実装なのでちょっと使いづらいですね)
hurousyotoku500

2020/11/26 20:48

.nilに変え、case-whenも使い方怪しいかなと思い、elsifに変えてみましたが、やはり「undefined method `between?' for nil:NilClass」が出てしまいます。
asm

2020/11/26 23:00 編集

回答に移動
asm

2020/11/26 23:00 編集

回答に移動
hurousyotoku500

2020/11/27 03:40

出来ました!ご丁寧にありがとうございます!
hurousyotoku500

2020/11/28 04:56

すみません…出来たと思っていたのですが、やはりa.nil?が検知出来ていないようで、1〜9Hまで全てスコアを入力した状態で、本来なら「アウトスタートで、アウト終了」と表示するところ、「なんか変なスコアのいれ方です」と表示されてしまいます。
asm

2020/11/28 06:33

<% else %>なんか変なスコアのいれ方です a=<%=a.inspect%>,b=<%=b.inspect%> にてまずはaに何が入っているかをご確認ください
hurousyotoku500

2020/11/28 12:38 編集

下記のようにデータを作成し出力してみました。 また、どの条件も.inspectでa,bそれぞれそのままの(-1していない)値も出力させました。 ①イン(10H)スタートで18Hまで入力  →なんか変なスコアのいれ方です a=1,b=10 ②アウト(1H)スタートで9Hまで入力  →Finish a=nil,b=nil ③イン(10H)スタートで10Hまで入力  →インスタートで、インプレイ中 a=1,b=11 ④18H全て完  →   (空白)
asm

2020/11/29 04:24

見た感じ、aおよびbの値がそれで正しければ判定は正しそうですね。 入力から作成された@thru_1h_startおよび@thru_10h_startが正しいか? @thru_1h_startおよび@thru_10h_startからとりだしたkey,a,bが正しいかを検証していくことになるかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問