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

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

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

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

Q&A

解決済

4回答

14542閲覧

nilであれば代入し、そうでなければ足す

akamakku

総合スコア191

Ruby

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

1グッド

4クリップ

投稿2016/11/22 08:31

最近メモ化を知りまして、同時に||の使い方を知りました。(論理式をORするだけだと思っていました。)

変数の値がnilであれば、代入するという処理は

Ruby

1arr[n] ||= x

と書くと思いますが、

「nilであれば代入し、そうでなければ足す」という処理は、if文などを使わずに、こういうスマートな書き方はできませんか?

これだと、

Ruby

1arr[n] = arr[n]+x || x

当たり前ですが、nilには+というメソッドはないよって言われてしまいます。

DrqYuto👍を押しています

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

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

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

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

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

guest

回答4

0

ベストアンサー

数値っていう前提だけど
Rubyでnilというのはオブジェクトでto_iを呼び出すと

nil.to_i #=> 0

と0が返ってくるので

arr[n] = arr[n].to_i + x

でいいかと。

投稿2016/11/22 13:02

schindler

総合スコア112

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

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

keys

2018/09/22 05:23

ありがとうございます。助かりました。
guest

0

xは数値(つまり、0+xxは同じになる)という前提で、9パターン作りました。一部最新バージョンでないと動きませんのでご注意ください。PineMatsuさんとtenu530さんの回答と被っているところもありますが、そこはご愛嬌で。

Ruby

1# Ruby 2.3.0 以上で実行してください。 2# 2.3.0 未満で実行する場合は パターン6 をコメントアウトしてください。 3# 2.2.0 未満で実行する場合は パターン5 もコメントアウトしてください。 4# 使い方 5# ruby このスクリプト 外か内か パターン 6# 外か内か ... 0 なら範囲外、1 なら範囲内でnilになる 7# パターン ... 実現9パターンを 1 から 9 の番号で指定 8# 例: ruby nil_kamo.rb 0 1 9# arr[n]がnilになる状態で、パターン1を試す。 10arr = [1, 2, 3] 11x = 100 12if ARGV[0].to_i == 0 13 n = 10 14else 15 n = 1 16end 17pattern = ARGV[1].to_i 18case pattern 19when 1 20 # まず普通に 21 if arr[n] 22 arr[n] += x 23 else 24 arr[n] = x 25 end 26when 2 27 # if式を戻り値に 28 arr[n] = if arr[n] 29 arr[n] + x 30 else 31 x 32 end 33when 3 34 # それをまとめて三項演算子 35 arr[n] = arr[n] ? arr[n] + x : x 36when 4 37 # あらかじめnilチェックして0にしておく 38 arr[n] ||= 0 39 arr[n] += x 40when 5 41 # それを一行で 42 arr[n] = (arr[n] || 0) + x 43when 6 44 # こういうときこそぼっち演算子 Ruby >= 2.3.0 45 arr[n] = arr[n]&.+(x) || x 46when 7 47 # リストとして処理… itself は Ruby >= 2.2.0 48 arr[n] = [arr[n], x].select(&:itself).inject(:+) 49when 8 50 # なければ常に0が返ればいいんだ 51 class ZeroArray < Array 52 def [](nth) 53 super(nth) || 0 54 end 55 end 56 arr = ZeroArray[1, 2, 3] 57 arr[n] += x 58when 9 59 # むしろ、サブクラスを作る必要すら無い! 60 def arr.[](nth) 61 super(nth) || 0 62 end 63 arr[n] += x 64else 65 puts "1 から 9 を引数にしてね" 66end 67p arr

お好みでお使いください。個人的に使うとしたらパターン4でしょうか。一番わかりやすいので。もっともRubyらしいのは最後の二つかと思ってます。関数型っぽいパターン7も通は好むかも知れません。

投稿2016/11/22 10:01

raccy

総合スコア21733

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

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

0

ruby

1arr[n] = arr[n].try(:+, x) || x

tryメソッドは引数で渡されたメソッド名を実行して、無かった場合はエラーを起こさずnilを返却します。
このtryメソッドと||演算子を使えば一応は一行でスマートに書けます。
しかしぱっと見で「何してるんだ」となりそうなので、
結局は読みやすさとの兼ね合いですね。

※追記
tryはRails環境にあるActiveSupportパッケージのメソッドなので、
Rails環境下でしか使えませんでした。
ご指摘くださったraccyさんありがとうございました。

投稿2016/11/22 09:11

編集2016/11/22 10:14
tenu530

総合スコア49

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

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

raccy

2016/11/22 09:29

tryはRailsに含まれるActiveSupportパッケージのメソッドなので、Rails環境またはActiveSupportを個別に読み込んだ環境でのみ使用可能という、注意書きが欲しいです。
tenu530

2016/11/22 09:55 編集

ご指摘ありがとうございます! rails console内でやっておりました
guest

0

3項演算子を使うと出来ます。

Ruby

1arr[n] = arr[n] ? (arr[n] + x) : x

3項演算子は複雑な文になると読みにくくなるので、そういう場合はifを使いましょう。

投稿2016/11/22 08:57

PineMatsu

総合スコア3579

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問