你例子表明不存在影響該表的外觀未指定的參數。例如,列標籤「表」和「字段」是左側調整的,而「預期值」和「實際值」不是。此外,「期望值」重疊「科目類型」。下面我建議你如何構建表格,但我做了妥協:左側調整所有列標籤,不垂直重疊。
代碼
def print_table(h, column_labels_and_spacing, table_label)
column_labels = column_labels_and_spacing.map(&:first)
column_spacing = column_labels_and_spacing[0..-2].map(&:last) << 0
rows = h.map { |k,f|
[table_label[k]].product(f.map { |field, g|
[[field, g.values.map(&:to_s)].flatten] }) }
.flat_map { |e| e.map(&:flatten) }.unshift(column_labels)
column_widths = rows.transpose.map { |c| c.max_by(&:size).size }
.zip(column_spacing).map { |a,b| a+b }
rows.each do |row|
row.zip(column_widths).each { |s, width| print s.ljust(width) }
puts
end
end
例
輸入
h = {"Table1"=>
{"Acct type"=>{"Expected"=>"ACC", "Actual"=>"ACC"},
"Seq No" =>{"Expected"=>"100.0", "Actual"=>100},
"Class" =>{"Expected"=>"AC", "Actual"=>"AC"}},
"Table 2"=>
{"Date" =>{"Expected"=>"20140606", "Actual"=>"20130606"}}}
column_labels_and_spacing = [["Table", 1], ["Field", 2],
["Expected", 3], ["Actual"]]
table_label = { "Table1"=>"Table 1", "Table 2"=>"Table 2" }
爲了簡化我轉換BigDecimal
值到Fixnum
說明。
Invoke方法
print_table(h, column_labels_and_spacing, table_label)
#-> Table Field Expected Actual
# Table 1 Acct type ACC ACC
# Table 1 Seq No 100.0 100
# Table 1 Class AC AC
# Table 2 Date 20140606 20130606
說明
對於上面的例子:
column_labels = column_labels_and_spacing.map(&:first)
#=> ["Table", "Field", "Expected", "Actual"]
column_spacing = column_labels_and_spacing[0..-2].map(&:last) << 0
#=> [1, 2, 3, 0]
a = h.map { |k,f|
[table_label[k]].product(f.map { |field, g|
[[field, g.values.map(&:to_s)].flatten] }) }
# => [[["Table 1", [["Acct type", "ACC", "ACC"]]],
# ["Table 1", [["Seq No", "100.0", "100"]]],
# ["Table 1", [["Class", "AC", "AC"]]]],
# [["Table 2", [["Date", "20140606", "20130606"]]]]]
要了解a
進行計算,考慮第一鍵值對h
傳遞給塊,密鑰被分配給所述塊變量k
和分配值,以f
:
k = "Table1"
f = { "Acct type"=>{ "Expected"=>"ACC", "Actual"=>"ACC" } }
塊然後執行以下計算:
b = f.map { |field, g| [[field, g.values.map(&:to_s)].flatten] }
# => [["Acct type", "ACC", "ACC"]]
c = ["Table 1"].product([[["Acct type", "ACC", "ACC"]]])
#=> [["Table 1", [["Acct type", "ACC", "ACC"]]]]
d = c.flatten
#=> ["Table 1", "Acct type", "ACC", "ACC"]
現在讓我們進行的,具有計算a
。計算表中的所述主體的所述行:
e = a.flat_map { |e| e.map(&:flatten) }
#=> [["Table 1", "Acct type", "ACC", "ACC"],
# ["Table 1", "Seq No", "100.0", "100"],
# ["Table 1", "Class", "AC", "AC"],
# ["Table 2", "Date", "20140606", "20130606"]]
然後添加列標籤:
rows = e.unshift(column_labels)
#=> [["Table", "Field", "Expected", "Actual"],
# ["Table 1", "Acct type", "ACC", "ACC"],
# ["Table 1", "Seq No", "100.0", "100"],
# ["Table 1", "Class", "AC", "AC"],
# ["Table 2", "Date", "20140606", "20130606"]]
接着,計算列寬度:
f = rows.transpose
#=> [["Table", "Table 1", "Table 1", "Table 1", "Table 2"],
# ["Field", "Acct type", "Seq No", "Class", "Date"],
# ["Expected", "ACC", "100.0", "AC", "20140606"],
# ["Actual", "ACC", "100", "AC", "20130606"]]
g = f.map { |c| c.max_by(&:size).size }
#=> [7, 9, 8, 8]
i = g.zip(column_spacing)
# => [[7, 1], [9, 2], [8, 3], [8, 0]]
column_widths = i.map { |a,b| a+b }
#=> [8, 11, 11, 8]
rows.each do |row|
row.zip(column_widths).each { |s, width| print s.ljust(width) }
puts
end
考慮第二印刷表格的行(列標籤之後的第一行):
row = ["Table 1", "Acct type", "ACC", "ACC"]
row.zip(column_widths)
# => [["Table 1", 8], ["Acct type", 11], ["ACC", 11], ["ACC", 8]]
第一字段被打印:
s = "Table 1"
width = 8
print s.ljust(width); puts ?:
#Table 1 :
其中I印刷結腸只是爲了顯示的字段寬度。其他字段的打印方式相似。
需要Ruby 1.9+才能知道首先將哪個鍵值對傳遞給塊。
請正確格式化並標記您的問題。你在用什麼語言? –
謝謝,更新了我的問題。 – Kiran
你應該檢查這個問題。 http://stackoverflow.com/questions/19534040/ruby-1-9-parse-hash-into-an-html-table –