2011-10-26 33 views
5

Có cách nào để nhanh chóng in một băm ruby ​​theo định dạng bảng thành một tệp không? Chẳng hạn như:Làm thế nào để nhanh chóng in các băm Ruby trong một định dạng bảng?

keyA keyB keyC ... 
123 234 345 
125   347 
4456 
... 

trong đó các giá trị của băm là các mảng có kích thước khác nhau. Hoặc đang sử dụng một vòng lặp đôi cách duy nhất?

Cảm ơn

+2

dễ nhất là một "vòng lặp kép", nhưng nó vẫn còn một lớp lót; nó có tệ không? –

+0

IMO quá chuyên biệt để trở thành một tính năng tích hợp và quá dễ dàng để thực hiện "bằng tay" :) –

+0

Sẽ không tệ nếu ai đó đăng bài dễ dàng. :-) – Larsenal

Trả lời

4

Dưới đây là một phiên bản của của steenslag rằng hoạt động khi các mảng không cùng kích thước:

size = h.values.max_by { |a| a.length }.length 
m = h.values.map { |a| a += [nil] * (size - a.length) }.transpose.insert(0, h.keys) 

nil có vẻ như một giữ chỗ hợp lý cho các giá trị bị mất tích nhưng bạn có thể, tất tất nhiên, sử dụng bất cứ điều gì có ý nghĩa.

Ví dụ:

>> h = {:a => [1, 2, 3], :b => [4, 5, 6, 7, 8], :c => [9]} 
>> size = h.values.max_by { |a| a.length }.length 
>> m = h.values.map { |a| a += [nil] * (size - a.length) }.transpose.insert(0, h.keys) 
=> [[:a, :b, :c], [1, 4, 9], [2, 5, nil], [3, 6, nil], [nil, 7, nil], [nil, 8, nil]] 
>> m.each { |r| puts r.map { |x| x.nil?? '' : x }.inspect } 
[:a, :b, :c] 
[ 1, 4, 9] 
[ 2, 5, ""] 
[ 3, 6, ""] 
["", 7, ""] 
["", 8, ""] 
2
h = {:a => [1, 2, 3], :b => [4, 5, 6], :c => [7, 8, 9]} 
p h.values.transpose.insert(0, h.keys) 
# [[:a, :b, :c], [1, 4, 7], [2, 5, 8], [3, 6, 9]] 
+1

Hoạt động miễn là các mảng có cùng độ dài. – Larsenal

1

Không, không có tích hợp chức năng. Dưới đây là mã sẽ định dạng theo ý bạn:

data = { :keyA => [123, 125, 4456], :keyB => [234000], :keyC => [345, 347] } 

length = data.values.max_by{ |v| v.length }.length 

widths = {} 
data.keys.each do |key| 
    widths[key] = 5 # minimum column width 

    # longest string len of values 
    val_len = data[key].max_by{ |v| v.to_s.length }.to_s.length 
    widths[key] = (val_len > widths[key]) ? val_len : widths[key] 

    # length of key 
    widths[key] = (key.to_s.length > widths[key]) ? key.to_s.length : widths[key] 
end 

result = "" 
data.keys.each {|key| result += key.to_s.ljust(widths[key]) + " " } 
result += "\n" 

for i in 0.upto(length) 
    data.keys.each { |key| result += data[key][i].to_s.ljust(widths[key]) + " " } 
    result += "\n" 
end 

# TODO write result to file... 

Mọi nhận xét và chỉnh sửa để trả lời câu hỏi đều được hoan nghênh.

3

Cố gắng đá quý này tôi đã viết (in băm, các đối tượng ruby, các đối tượng ActiveRecord trong bảng): http://github.com/arches/table_print

+0

tp không hoạt động trên băm cung cấp, nó hoạt động trên một đối tượng AR. Khi tôi thử trên một băm, tôi nhận được điều này => table_print-1.0.1/lib/table_print/fingerprinter.rb: 38: trong 'block in populate_row ' –

+0

Nói chung nó hoạt động trên băm. Nếu nó không hoạt động cho bạn, hãy mở một vấn đề tại http://github.com/arches/table_print hoặc gửi email cho tôi về vấn đề của bạn ([email protected]) –

+0

lỗi sau khi cập nhật lên phiên bản mới nhất, vẫn còn không phải là người đang tìm kiếm, nhưng đối với điều bảng, nó có vẻ tốt nhất –

Các vấn đề liên quan