以下のようなcsvファイルを用意。
aaa.doc,fujihara,10 aaa.doc,aragaki,14 aaa.doc,nagasawa,39 bbb.doc,fujihara,9 bbb.doc,aragaki,14 bbb.doc,nagasawa,22 ccc.doc,fujihara,0 ccc.doc,nagasawa,17 ddd.doc,fujihara,8 ddd.doc,aragaki,29 ddd.doc,nagasawa,11
aaa.docにはfujiharaという文字が10回あります。という意味になっている。これをドキュメントごとに集計してみる。
はまったところ
Rubyでまじめに書いたのが今回が初めてだったので、全体的にはまったのだが、その中で調べてわかったことのみを記述。
loggerってないの?
あった。
require 'logger'
class CreateHTML
# コンストラクタ
def initialize(input, output)
@input = input
@output = output
@results = {}
@log = Logger.new(STDOUT)
@log.level = Logger::DEBUG
end
これで「@log.debug(“俺は天才”)」のように使えるらしい。出力はSTDOUTにしている。
インスタンス変数って何?
今回はクラスを作ってみたけど、newしたクラスごとにもつ変数を「@fujihara」みたいに定義できるらしい。
連想配列みたいなのある?
ある。「@results = {}」みたいに宣言して「@results[‘fujihara’]」みたいにいれれるらしい。ただ、書いてみたらうまくいってるように思えない。
# ファイル内容を集計 def count(line) array = line.split(/,/) if @results[array[0]] # 回数を集計 @results[array[0]] = @results[array[0]].to_i + array[2].to_i else @results[array[0]] = array[2].to_i end end
これを実行すると、「[[“aaa.doc”, 63], [“ddd.doc”, 48], [“bbb.doc”, 45], [“ccc.doc”, 17]]」みたいになるおっかしいなーとおもったけど、配列の要素名をとる手段がよくわからずあきらめ。。
ファイル読み込みってどうやるの?
fr = open(@input, "r") # ファイル読み込み # 1行ずつ読み込んで集計 while line = fr.gets count(line) end fr.close
ファイル書き込みってどうやるの?
fw = open(@output, "w")
fw.puts('うんこ')
fw.close
CVSファイルの処理って簡単にできないかな?
デリミタをカンマとしてArrayに変換するには「array = line.split(/,/)」とする。
配列のソートってどうやるの?
これもよくわかってないけど以下でできた。
@results = @results.sort{|a, b| b[1] <=> a[1]}
文字コードってどこで指定するの?
$KCODEという変数で指定するらしい。ファイルの頭で「$KCODE=’UTF-8’」としていした。Rubyはこの変数の頭1文字だけ読んでるらしい。
これでなんとかできました
