2015-01-13 92 views
0

我有紅寶石嵌套散列:轉換嵌套在紅寶石散列到一個表格式

{"Table1"=>{"Acct type"=>{"Expected"=>"ACC", "Actual"=>"ACC"}, "Seq No"=>{"Expected"=>"100.0", "Actual"=>#<BigDecimal:56d0b28,'0.1E3',9(18)>}, "Class"=>{"Expected"=>"AC", "Actual"=>"AC"}}, "Table 2"=>{"Date"=>{"Expected"=>"20140606", "Actual"=>"20130606"}}} 

我需要顯示在表格格式上述嵌套散列 -

Table Field Expected Value Actual Value 
Table 1 Acct type ACC   ACC 
Table 1 Seq No  100.0   100.0 
Table 1 Class  AC    AC 
Table 2 Date  20140606  20130606 

任何建議/指針會非常有幫助。我曾嘗試使用'tableprint'和'text-table'寶石,但無法獲得理想的效果。上述數據是使用ActiveRecord從DB2表中獲取的。

+1

請正確格式化並標記您的問題。你在用什麼語言? –

+0

謝謝,更新了我的問題。 – Kiran

+0

你應該檢查這個問題。 http://stackoverflow.com/questions/19534040/ruby-1-9-parse-hash-into-an-html-table –

回答

0

這裏是一個解決方案:

x = { 
    "Table1"=>{ 
    "Acct type"=>{"Expected"=>"ACC", "Actual"=>"ACC"}, 
    "Seq No"=>{"Expected"=>"100.0", "Actual"=> 100.00}, 
    "Class"=>{"Expected"=>"AC", "Actual"=>"AC"} 
    }, 
    "Table 2"=>{ 
    "Date"=> {"Expected"=>"20140606", 
       "Actual"=>"20130606"}}} 

def table_row(row_name, row_values) 
    [row_name, row_values["Expected"], row_values["Actual"]] 
end 

def table_rows(table_hash) 
    table_hash.map do |field_name, field_values| 
    table_row(field_name, field_values) 
    end 
end 

def widest_string_lengths(visual_table) 
    table_columns_count = visual_table.first.size - 1 
    0.upto(table_columns_count).map do |index| 
    columns = visual_table.map { |row| row[index].to_s } 
    columns.max_by(&:length).length + 2 
    end 
end 

def aligned_visual_table(visual_table) 
    widest_string_items = widest_string_lengths(visual_table) 

    visual_table.map do |row| 
    row.each_with_index.map do |cell, index| 
     cell.to_s.ljust(widest_string_items[index] + 2) 
    end 
    end 
end 

table_headers = ['Table', 'Field', 'Value', 'Actual Value'] 

# This just turns the hash to array of arrays 
visual_table = x.map do |table_name, table_hash| 
    table_rows(table_hash).map do |table_rows| 
     table_rows.insert(0, table_name) 
    end 
end.flatten(1).insert(0, table_headers) 

puts "*********" 
puts aligned_visual_table(visual_table).map(&:join).join("\n") 
+0

真棒!!!!它工作了,謝謝,一噸。 – Kiran

0

你例子表明不存在影響該表的外觀未指定的參數。例如,列標籤「表」和「字段」是左側調整的,而「預期值」和「實際值」不是。此外,「期望值」重疊「科目類型」。下面我建議你如何構建表格,但我做了妥協:左側調整所有列標籤,不垂直重疊。

代碼

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+才能知道首先將哪個鍵值對傳遞給塊。