Sun~sun~Flower's

日々前向きに頑張る為のブログ

MENU

【Railsアプリケーション】任意の数値(a,b,c)の合計を出力する方法

f:id:mTakata:20201229152622j:plain

更新日:2020/12/30(水)

こんにちは。

当ページにアクセスしてくださり、ありがとうございます。

 

この記事は、プログラミング言語「Ruby」のフレームワーク「Rails」についての記事になります。

問題

任意の3つの数値(a,b,c)の合計を出力するメソッドを作りましょう。


ただし同じ数が含まれている場合、合計にはカウントされないようにして下さい。

 

※わからない場合は次のAPIを利用してみてください。

【参考記事】

docs.ruby-lang.org

出力例:

lone_sum(1, 2, 3) → 6
lone_sum(3, 2, 3) → 2
lone_sum(3, 3, 3) → 0

 

模範回答

def lone_sum(ary)
# 1. 配列から、重複する要素を取り出す↓↓
  un_uniqs = []
  ary.each_with_index do |n, i|
    cp_ary = ary.drop(i+1)
    cp_ary.each do |cn|
      un_uniqs << n if n == cn
    end
  end

  # 2. 重複した要素をuniqする↓↓
  uniq_un_uniqs = un_uniqs.uniq

  # 3. 重複する数字と元の配列の数字を比較し、もし重複する数字でなければ足し合わせる↓↓
  ary.inject(0) {|n, item| uniq_un_uniqs.include?(item) ? n + 0 : n + item }
end

解説

上記のコードでやろうとしている事は次の通りです。

 

「#1. 配列から、重複する要素を取り出す」でやっていること

    # 1. 配列から、重複する要素を取り出す↓↓
  un_uniqs = []
  ary.each_with_index do |n, i|
    cp_ary = ary.drop(i+1)
    cp_ary.each do |cn|
      un_uniqs << n if n == cn
    end
  end

①配列aryの中身を、1つずつ見にいく(ary.each_with_index do |n, i| の部分)

 

②見に行っている要素以外の配列を、cp_ary(配列)として作成する。(cp_ary = ary.drop(i+1)の部分)

 

例えば、ary = [1, 2, 3] の場合で、要素番号0(aryでは「1」に該当します)を見に行っている時、cp_ary = ary.drop(1)で、cp_aryには[2, 3]が格納されるイメージです。

 

③今度は、cp_aryの中身を、1つずつ見に行きます。(cp_ary.each do |cn|の部分)

 

④前の要素番号に格納された数値と、現在見に行っている要素番号に格納された数値が等しいかどうか??を確認(un_uniqs << n if n == cnの、if n == cnです)

 

⑤④で値が等しかった場合、変数un_unips(配列)に配列aryの値nを格納します。(un_uniqs << n if n == cnの、un_uniq << nです

 

例えば、ary = [1, 1, 3]とcp_ary = [1, 3]の場合で、cp_aryの最初の要素を見に行っている時、if文でn(aryの数値「1」)とcn(cp_aryの数値「1」)が等しいかを確認します。

 

上記例の場合ですと、nとcnが等しいので、un_unipにnの中身である「1」が格納されるという流れです。

 

上記①〜⑤を配列に格納されている分だけ繰り返します。

 

これで配列un_uniqsには、aryから重複した値のみが格納されています。

 

例えば、aryが[1, 1, 2]の時、un_uniqsは[1]になります。

 

「# 2. 重複した要素をuniqする」でやっていること

  # 2. 重複した要素をuniqする↓↓
  uniq_un_uniqs = un_uniqs.uniq

⑥重複した要素をuniqメソッドを使うことで、重複しないように整理してくれます。

 

例えば、un_uniqsが[1, 1, 3, 4, 5, 3]の場合、uniqメソッドを使用すると[1, 3, 4, 5]となります。

 

これで重複がなくなりましたよね。

 

そして配列uniq_un_uniqsを用意して、un_uniqsにuniqメソッドを使用した結果を格納するという感じです。

 

ちなみに配列uniq_un_uniqsは、

あくまで配列aryの中で重複している値を取り出したもの

上記であることを頭に置いておいてくださいね。

 

「# 3. 重複する数字と元の配列の数字を比較し、もし重複する数字でなければ足し合わせる」でやっていること

 # 3. 重複する数字と元の配列の数字を比較し、もし重複する数字でなければ足し合わせる↓↓
  ary.inject(0) {|n, item| uniq_un_uniqs.include?(item) ? n + 0 : n + item }

⑦今回の問題では、「重複する数値は計算しない」というルールですので、あとは計算対象の配列aryと重複した値を格納した配列uniq_un_uniqを比較しています。

 

比較して等しくなければ、重複しない数値と見なし、計算されるという感じです。(等しければ、計算しません。)

 

上記①〜⑦の流れで、任意の数値の合計を出力しています。

 

今回はかなり複雑なので、理解するのに苦しむと思いますが、頑張って理解頂ければと思います。

 

以上となります、参考になれば幸いです。

 

最後まで読んでいただき、ありがとうございました。