Hashの配列を表にする

うまい書き方ができない…orz

ソース


#!/usr/local/bin/ruby

class TableWriter
def initialize(rows)
return if rows.size < 1
@rows = rows
set_names
set_sizes
end

def to_s
return "Empty set" unless @rows
buf = ""
puts_line(buf)
puts_names(buf)
puts_line(buf)
@rows.each {|row| puts_row(row, buf)}
puts_line(buf)
return buf
end

private
def set_names
@names = @rows.first.keys
end

def set_sizes
@sizes = {}
@names.each {|name| @sizes[name] = name.size}
@rows.each {|row|
row.each {|name, val|
size = val.to_s.size
@sizes[name] = size if @sizes[name] < size
}
}
end

def rpad(str, len)
return str + " " * (len - str.length)
end

def puts_names(buf)
append_row(@names.collect {|name| rpad(name, @sizes[name])}, buf)
end

def puts_row(row, buf)
append_row(@names.collect {|name| rpad(row[name].to_s, @sizes[name])}, buf)
end

def puts_line(buf)
append_row(@names.collect {|title| "-" * @sizes[title]}, buf, "+")
end

def append_row(ary, buf, sep="|")
buf << sep + ary.join(sep) + sep + "\n"
end
end

rows = []
rows << {"ID"=>"001", "NAME"=>"Yamada Taro", "AGE"=>21}
rows << {"ID"=>"002", "NAME"=>"山田花子", "AGE"=>18}
rows << {"ID"=>"003", "NAME"=>"Suszuki Ichiro", "AGE"=>28}

puts TableWriter.new(rows)

実行結果

~/work$ ./table.rb
+--------------+---+---+
|NAME          |ID |AGE|
+--------------+---+---+
|Yamada Taro   |001|21 |
|山田花子      |002|18 |
|Suszuki Ichiro|003|28 |
+--------------+---+---+