memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

同一内容を含むデータ個数をカウントしたい(の答えです)

そういえば忘れてた。。。

同一内容を含むデータ個数をカウントしたい(問題のみ) - memorandums

答えの1つが以下です。もうどこまでも生真面目なアルゴリズムです。1行読み込んでは、その前に読み込んだ内容を比較して同一ならカウントアップする。。。という流れです。

本当はFile.openを使うべきでしょうけど、ファイルをリダイレクトで読み込むことを想定して。。。入力は標準入力、出力は標準出力にしています。

fn2 = ""
c = 1
while fn1 = gets&.chomp
  if fn1 == fn2
    c += 1
  else
    puts "#{fn2},#{c}" if c >= 1 and fn2 != ""
    c = 1
  end
  fn2 = fn1
end
puts "#{fn2},#{c}" if c >= 1 and fn2 != ""

さて、もっといいアイデアはありますでしょうか?別案を示します。ハッシュを使って文字列ごとの個数を管理しようとしました。この2つは昨年思いついたものでした。

data = []
while s = gets
  data << s.chomp
end

tmp = {}
data.each do |item|
  if tmp.key?(item)
    tmp[item] << item
  else
    tmp[item] = [item]
  end
end

tmp.each_key do |key|
  print key, ",", tmp[key].size, "\n"
end

で、今年、改めて作ってみたのが以下。短くなりましたね。。。ハッシュを使うというアイデアは変わりありませんが、使い方に工夫ができました。最適ではないでしょうけど、準最適解という感じにも思います。

a = Hash.new
while s = gets&.chomp
  a[s] = (a[s] or 0) + 1
end
a.each do |key, value|
  puts "#{key},#{value}"
end

ちなみに、SQLを使うと。。。たったの1行。。。以下、Google スプレッドシートで実行した例です。

A列に重複があるデータをいれると、B1に入れたQuery関数が自動的に実行されて、B2以下に結果が出力されます。最初は空のデータはないので0件、つぎにaが2件。。。という感じに求められます。

f:id:ke_takahashi:20190706224608p:plain

Excelも便利ですが、Googleスプレッドシートはもっと便利です。GASも便利だしな。。。ITエンジニアじゃなくても、一般の人でもこの辺ができるようになると仕事が捗るんじゃないかな。。。と。思います。