##この記事について
最近始めたCodewarを通じて学べたことを少しずつアウトプット
##問題
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in.
Note: If the number is a multiple of both 3 and 5, only count it once. Also, if a number is negative, return 0(for languages that do have them)
10未満の数字の内で3と5の倍数の数字を合計して、その値を返すメソッドを作成する。
注意点が数が3と5の両方の倍数である場合(15の倍数)は、1回だけ数えるようにする。
###僕の回答
ほぼほぼFizzBuzzの回答やね。
https://qiita.com/Fendo181/items/425293e8e638d7fd7cea
def solution(number)
i = 1
nums_array = []
number -= 1
number.times do
nums_array << i
i += 1
end
sum = 0
nums_array.each do |num|
if num % 3 == 0 && num % 5 == 0
sum += num
elsif num % 3 == 0
sum += num
elsif num % 5 == 0
sum += num
end
end
sum
end
###ベストプラクティス
「なるほど〜」と「なにこれ?」が混在している。
def solution(number)
(1...number).select {|i| i%3==0 || i%5==0}.inject(:+)
end
###なるほど〜
####(1...number)
問題文にある通り、10未満の数字で該当の倍数を探して行くんだから、最後の数字は含まない1...10
という風にしてあげている。ちなみに最後の数字も含みたい場合は1..10
とコンマの数を2つにする。
####select {|i| i%3==0 || i%5==0}
selectで各要素をブロックで評価して、3の倍数もしくは5の倍数である要素を抽出している。
これだけ15の倍数で合っても2回カウントされることはない。
###なにこれ?
####inject(:+)
injectはeachやmapと同じように繰り返しを行うメソッドとのこと。つまり、3の倍数もしくは5の倍数である要素を抽出した結果を順番に足し算をする処理しようとしている。よく使われるのは繰り返し計算を行うことみたい。
#####基本的な使い方
https://blog.toshimaru.net/ruby-inject/
配列オブジェクト.inject {|初期値, 要素| ブロック処理 }
array = 1..6
array.inject (0){ |sum,num| p sum+=num}
=>1
3
6
10
15
21
#inject(0)の0はsumの初期値を設定。
#ただ、injectのデフォルト引数設定は0なので下記のように省略することが可能
#numはarrayの要素
####今回のinject(:+)
は何者?
シンボルで演算子を渡してやると以下のように省略して書くことができる便利なやつ。
array = 1..10
array.inject {|sum,num| sum+=num}
=> 55
#省略して書いても同じ結果
array = 1..10
array.inject(:+)
=> 55
###まとめ
これまではeachメソッド
を使用してそのブロック内で計算しようとしていたけど、今後繰り返し処理で計算するときはinjectメソッドを使用します!!!