質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

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

Ruby on Rails

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

Q&A

3回答

812閲覧

Ruby でarrayの中身のint を比較する

ShowGoTagami

総合スコア13

Ruby

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

Ruby on Rails

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

1グッド

1クリップ

投稿2019/03/09 13:33

ゲームアプリでよくある「XXつのポイントを獲得しました!」のように、一定のポイント数になったらテキストを表示するような処理をシンプルに書く方法がないでしょうか?

具体的には、

point modelの中のクラスメソッドで、受け取った point が以下の

POINT_STEP = [5,10,15,20,25,30,50,100]

というステップのどこにいるか、を処理して、達成しているステップがあれば、そのintを抜き出して、 pointテーブルのstepカラムにそのintを入れるようなイメージです。

例えば、
point = 3 > (達成したステップがないので) step: null
point = 5 > (POINT_STEPの5を達成したので) step: 5
point = 12 > (POINT_STEPの10を達成したので) step: 10

というかたちをシンプルに書けないでしょうか。

DrqYuto👍を押しています

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

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

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

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

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

guest

回答3

0

Ruby

1POINT_STEP.sort.reverse.bsearch(&point.method(:>=))

(&point.method(:>=))部分は{ |x| point >= x }と同じです。

とすれば実現出来るかと思います。今回のように既にソート済みならsortは書く必要はありません。

単純に「ある条件を満たす最初の要素」を返す場合はfindが使えます。しかし、大きさを比較可能な要素からなるソート済みの配列の場合はbsearhを使った方が高速になります。ただここで問題なのは与えられたPOINT_STEPは昇順であるため、『ある値以下の最後の要素』を探す必要があり、これでは「ある条件を満たす最初の要素」ではなくという「ある条件を満たす最後の要素」の形になってしまいます。それを実現するようなメソッドはありませんが、逆に降順であったならば、『ある値以下の最初の要素』を探すことになり、「ある条件を満たす最初の要素」の形になります。つまり、

ある数列において有る値以下の数のうちで最も大きい数

昇順で並んだ数列のある値以下の最後の数

降順で並んだ数列のある値以下の最初の数

は同じであると言うことです。このことから、POINT_STEPを昇順でソート(sort)し、逆順にする(reverse)することで降順の数列を得て、その数列において、最初に現れるpoint以下の数を求める(bsearch(&point.method(:>=)))とすればよいとなります。

投稿2019/03/09 14:38

編集2019/03/09 14:44
raccy

総合スコア21735

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

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

0

ruby

1POINT_STEPS = [5,10,15,20,25,30,50,100] 2 3def point_to_step(point) 4 POINT_STEPS.reverse_each do |p| 5 return p if p < point 6 end 7 nil 8end 9 10[0,3, 10, 99, 101].each do |p| 11 puts "#{p} -> #{point_to_step(p)}" 12end

のような point_to_step メソッドをつくって

ruby

1... 2step: point_to_step(point), 3...

とすればよいのでは?

投稿2019/03/09 14:18

katoy

総合スコア22324

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

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

0

2分探索する場合

ruby

1POINT_STEP = [5,10,15,20,25,30,50,100] 2 3def search(i) 4 ix = POINT_STEP.bsearch_index{|x| x > i} || POINT_STEP.size 5 POINT_STEP[ix - 1] if ix > 0 6end 7 8p [3, 5, 12, 2500].map{|i| search(i)} 9# => [nil, 5, 10, 100]

線形探索する場合

ruby

1POINT_STEP = [5,10,15,20,25,30,50,100] 2 3def search(i) 4 ix = POINT_STEP.rindex{|x| x <= i} 5 POINT_STEP[ix] if ix 6end 7 8p [3, 5, 12, 2500].map{|i| search(i)} 9# => [nil, 5, 10, 100]

投稿2019/03/09 14:18

asm

総合スコア15147

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

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

asm

2019/03/09 14:22

rindexよりもtake_while{|x| x <= i}.lastのがよさげ
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問