ずみーBlog

元クラゲ研究者(見習い)の92年生まれがエンジニアを目指しながら日々寄り道するブログです。

配列の中で重複していないものだけを合計する

やりたいこと

Rubyで、配列で渡される数値の合計値を出力するメソッドが作りたい。 ただし、渡された配列内で値が重複している数字は除いて合計を計算する。

出力例

lone_sum([1, 2, 3]) # → 6
lone_sum([3, 2, 3]) # → 2
lone_sum([3, 3, 3]) # → 0

最初に考えたこと

  • シンプルに配列をループで回せばできそうだが、つまらない
  • 一行でバシッと返せたらかっこいい(可読性はきっとサイテーだけど)

次の手順でできそう。
1. 数字ごとにグルーピングする
2. 数字ごとに何個ずつ含まれているかをハッシュで表す
3. 得られたハッシュから、個数が1個のもののみを取り出して配列にする
4. 配列の合計を計算する

できた!

パフォーマンスに関しては未調査です。

def lone_sum(arr)
  puts arr.group_by{|i| i}.select{|k,v| v.length == 1}.keys.sum
end

調査したこと

まずは1. 数字ごとにグルーピングする2. 数字ごとに何個ずつ含まれているかをハッシュで表すから。

配列.group_by

array.group_by {|i| 式}で、ブロックの式を評価した結果でグルーピングしてくれる。戻り値はハッシュ構造になる。

instance method Enumerable#group_by

次に、3. 得られたハッシュから、個数が1個のもののみを取り出して配列にするをやっていく。 手順は2つに分けられる: 1. ハッシュに「個数=1個」でフィルタをかける 2. フィルタを通過した要素のキーのみを取り出して配列にする

ハッシュ.select

keyとvalueのペアについてブロックを評価して、合格する(trueを返す)ものだけを含むハッシュを返してくれる。

instance method Hash#filter

ハッシュ.keys

ハッシュからkeyのみを取り出し、配列にして返してくれる

ハッシュに含まれるキーや値を配列として取得

最後に、4. 配列の合計を計算するでキメる。

配列.sum

instance method Array#sum

後記

Rubyの文法練習のために、あえてなるべく複雑な方法でやってみました。案の定可読性は落ちています。 しかし、知らないメソッドを調べながら一つ一つ積み上げていく感覚が快感ですね。