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

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

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

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

Q&A

解決済

3回答

289閲覧

Rubyのinjectについて

abab7200

総合スコア120

Ruby

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

0グッド

0クリップ

投稿2017/07/10 07:07

ruby2.1系でrubyシルバーの自習をしております。
その際 コードの i > j ? i : jの部分がどういう処理が行われているか
理解できず、どなたかご教授いただければと存じます

※injectについては配列内の値の合計と理解しております。

コード

numbers = [3,89,40,39,29,10,50,59,69] num = numbers.inject do |i,j| i > j ? i : j end p num #89

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

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

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

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

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

guest

回答3

0

ベストアンサー

ruby2.1系でrubyシルバーの自習をしております。

その際 コードの i > j ? i : jの部分がどういう処理が行われているか
理解できず

シルバーの勉強をするのあれば、まずRubyの文法を一通り理解した方が良いと思いますよ。
メソッドを全部暗記する必要なはないですが、基本構文や、演算子は暗記する必要があります。

i > j ? i : jは他の方が書いているように「大きい方(正確には小さくない方)」を得る記述です。

injectは英語で「注入する」という意味です。
[3,89,40,39].inject(&:+)
であれば、配列の要素の間に + が注入され、
3 + 89 + 40 + 39
になります。実行順序を括弧で表すと、((3 + 89) + 40) + 39です。
[3,89,40,39].inject(&:-)
であれば、
3 - 89 - 40 - 39((3 - 89) - 40) - 39
になります。

[3,89,40,39].inject { |i,j| i > j ? i : j }
でも同じく、それぞれの間に、両項の大きい方を取るというメソッドが注入され、
((3と89の大きい方)と40の大きい方)と39の大きい方
になります。

投稿2017/07/10 13:06

otn

総合スコア84505

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

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

abab7200

2017/07/11 04:30

詳細なご解説ありがとうございます! 理解しました!
guest

0

i > j ? i : j の様な式の事を三項演算子と呼びます。? よりも手前の評価値が真ならば : の左項を、評価値が偽ならば : の右項を返します。

ですので a == "hello" ? "foo" : "bar" この式は「変数 a の値が "hello" ならば foo、そうでないならば bar」を返す式になります。

ruby の場合、関数の戻り値を返す際に明示的に return を書かない場合は最終評価値が返る事になっていますので、これは

return i > j ? i : j

さらに言うと

if i > j return i else return j end

と同じ意味になります。さて inject の仕様を見ると

injectメソッドは、ブロックを使って繰り返し計算を行うのに使います。ブロックに順に「要素1、要素2」、「ブロックの前回の戻り値、要素3」、「ブロックの前回の戻り値、要素4」、...を渡します。メソッドの戻り値はブロックが最後に返した値になります。

となっています。この「ブロックの前回の戻り値」がミソで、例えば配列の先頭2つ 3 と 89 を渡すと、i > j ? i : j は 89 の方が大きいので偽、つまり j(89) が返ります。その 89 と 49 で次のブロックが実行され、89 の方が大きいので j(89) が返ります。もうお気付きだと思いますが、これは2項を得て大きい方の数値を返す関数で、つまりは配列の中から一番大きい値を返す処理になるのです。

投稿2017/07/10 09:13

編集2017/07/10 09:32
mattn

総合スコア5030

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

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

abab7200

2017/07/11 04:30

ありがとうございます!
guest

0

i > j ? i : jに関してはif文を1行で書く記法になります。(知らないとわかりづらいですよね)
以下と同じです。

ruby

1if i > j 2 return i 3else 4 return j 5end

ただ、

※injectについては配列内の値の合計と理解しております

の理解は違うと思いますよ。

こちらのリンクが参考になりますが、
イメージは配列をループさせて前回の結果に処理結果をくっつけてい感じです。

実際の動きですと、、、
初回 i = 3, j = 89 が渡されて、 89を返す
2回目 i=89(前回の結果), j = 40が渡されて、89を返す
3回目 i=89(前回の結果), j = 39が渡されて、89を返す
...
という感じです。

以下で実行したほうがイメージわくかも

ruby

1numbers = [3,89,40,39,29,10,50,59,69] 2num = numbers.inject do |i,j| 3 p "=================" 4 p "iの値は#{i}" 5 p "jの値は#{j}" 6 p "なので i > j ? i: jの結果は#{i > j ? i : j}を返します" 7 i > j ? i : j 8end

投稿2017/07/10 07:37

h_daido

総合スコア824

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

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

abab7200

2017/07/11 04:30

参考リンクありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問