Class: ColumnFormatter
Overview
Displays a set of data into a column-formatted table
Constant Summary collapse
- MARGIN =
1
- SCREEN_WIDTH =
80
Class Method Summary collapse
-
.from_hashes(data, io = STDOUT, options = Hash.new) ⇒ Object
Formats the given array of hash column-wise.
Class Method Details
.from_hashes(data, io = STDOUT, options = Hash.new) ⇒ Object
Formats the given array of hash column-wise.
data
is an array of hash. In this array, each element is a sample. The column names are defined from the hash keys. If one hash does not have a value for a column, “-” is displayed instead.
In the output, the columns are ordered alphabetically by default. Alternatively, they can be ordered by giving an :order option which is an array of string:
from_hashes(data, STDOUT, :order => %w{Col0 Col1 Col2})
Finally, the method can yield the set of available columns to a block (if given), and this block should return an ordered array of string.
In both cases, columns not listed in the ordering array are not displayed.
The formatting can be controlled by the following options:
- header_delimiter
-
if true, displays a line of dashes between the header and the rest of the table
- column_delimiter
-
a string that is inserted between columns
- left_padding
-
a string that is inserted in front of each line
- order
-
an array of column names, defining which columns should be displayed, and in which order they should be displayed. See above for more explanations.
- screen_width
-
if the table is wider than this count of characters, it is split into multiple tables.
- margin
-
defines how many spaces are inserted between two columns.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/utilrb/column_formatter.rb', line 43 def self.from_hashes(data, io = STDOUT, = Hash.new) = , :margin => MARGIN, :screen_width => SCREEN_WIDTH, :header_delimiter => false, :column_delimiter => "", :left_padding => "", :order => nil margin = [:margin] screen_width = [:screen_width] width = Hash.new # First, determine the columns width and height, and # convert data into strings data = data.map do |line_data| line_data = line_data.inject({}) do |h, (label, value)| h[label.to_s] = value.to_s h end line_data.each do |label, value| unless width.has_key?(label) width[label] = label.length end if width[label] < value.length width[label] = value.length end end end # Then ask the user to sort the keys for us names = width.keys.dup names.delete('label') names = if [:order] then [:order] elsif block_given? then yield(names) else names.sort end # Finally, format and display while !names.empty? # we determine the set of columns to display if width.has_key?('label') line_n = ['label'] line_w = width['label'] format = ["%-#{line_w}s"] else line_n = [] line_w = 0 format = [] end while !names.empty? && (line_w < screen_width) col_n = names.shift col_w = width[col_n] || 0 line_n << col_n line_w += col_w format << "%-#{col_w}s" end format = format.join(" " * margin + [:column_delimiter] + " " * margin) header_line = format % line_n io.puts [:left_padding] + header_line if [:header_delimiter] io.puts [:left_padding] + "-" * header_line.length end format = [:left_padding] + format data.each do |line_data| line_data = line_data.values_at(*line_n) line_data.map! { |v| v || '-' } io.puts format % line_data end end end |