Class: TableData::Table
- Inherits:
-
Object
- Object
- TableData::Table
- Includes:
- Enumerable
- Defined in:
- lib/tabledata/table.rb
Overview
This class represents the tabular data.
Constant Summary collapse
- DefaultOptions =
The default options for TableData::Table#initialize
{ has_header: true, has_footer: false, # currently unused accessors: [], }
Instance Attribute Summary collapse
-
#accessor_columns ⇒ Hash<Symbol => Integer>
readonly
A hash mapping column accessor names to the column index.
-
#accessors ⇒ Array<Symbol>
An array of all named accessors.
-
#data ⇒ Object
readonly
The internal data structure.
Class Method Summary collapse
-
.from_file(path, options = nil) ⇒ TableData::Table
All other options are passed on to Parser.parse_csv, .parse_xls or parse_xlsx, which in turn passes remaining options on to Table#initialize.
Instance Method Summary collapse
- #<<(row) ⇒ Object
-
#[](*args) ⇒ Array<TableData::Row>
Array#[] like access to the rows in the body of the table.
- #accessors? ⇒ Boolean
- #body ⇒ Object
- #cell(row, column, default = nil) ⇒ Object
- #column(index) ⇒ Object
- #column_accessor(index) ⇒ Object
-
#column_count ⇒ Integer
The number of columns.
- #column_name(index) ⇒ Object
- #columns ⇒ Object
-
#each {|row| ... } ⇒ self
Iterate over all rows in the body.
-
#each_column {|column| ... } ⇒ self
Iterate over all columns.
-
#each_row {|row| ... } ⇒ self
Iterate over all rows, header and body.
- #format(format_id, options = nil) ⇒ Object
- #headers ⇒ Object
- #headers? ⇒ Boolean
- #index_for_accessor(name) ⇒ Object
- #index_for_header(name) ⇒ Object
-
#initialize(data = [], options = nil) ⇒ Table
constructor
A new instance of Table.
- #inspect ⇒ Object
- #row(row) ⇒ Object
-
#size ⇒ Object
(also: #length)
The number of rows, excluding headers.
- #to_a ⇒ Object
- #to_nested_array ⇒ Object
Constructor Details
#initialize(data = [], options = nil) ⇒ Table
Returns a new instance of Table.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/tabledata/table.rb', line 57 def initialize(data=[], =nil) = ? self.class::DefaultOptions.merge() : self.class::DefaultOptions.dup column_count = data.first ? data.first.size : 0 @has_header = .delete(:has_header) ? true : false @data = data @rows = data.map.with_index { |row, index| raise InvalidColumnCount, "Invalid column count in row #{index} (#{column_count} expected, but has #{row.size})" if index > 0 && row.size != column_count raise ArgumentError, "Row must be provided as Array, but got #{row.class} in row #{index}" unless row.is_a?(Array) Row.new(self, index, row) } @column_count = nil @header_columns = nil @accessor_columns = {} @column_accessors = {} @accessors = [].freeze self.accessors = .delete(:accessors) end |
Instance Attribute Details
#accessor_columns ⇒ Hash<Symbol => Integer> (readonly)
Returns A hash mapping column accessor names to the column index.
51 52 53 |
# File 'lib/tabledata/table.rb', line 51 def accessor_columns @accessor_columns end |
#accessors ⇒ Array<Symbol>
Returns An array of all named accessors.
48 49 50 |
# File 'lib/tabledata/table.rb', line 48 def accessors @accessors end |
#data ⇒ Object (readonly)
The internal data structure. Do not modify.
55 56 57 |
# File 'lib/tabledata/table.rb', line 55 def data @data end |
Class Method Details
.from_file(path, options = nil) ⇒ TableData::Table
All other options are passed on to Parser.parse_csv, .parse_xls or parse_xlsx, which in turn passes remaining options on to Table#initialize
34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/tabledata/table.rb', line 34 def self.from_file(path, =nil) ||= {} [:table_class] ||= self [:file_type] ||= Detection.file_type_from_path(path) case [:file_type] when :csv then Parser.parse_csv(path, ) when :xls then Parser.parse_xls(path, ) when :xlsx then Parser.parse_xlsx(path, ) else raise InvalidFileType, "Unknown file format #{[:file_type].inspect}" end end |
Instance Method Details
#<<(row) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/tabledata/table.rb', line 174 def <<(row) index = @data.size raise InvalidColumnCount, "Invalid column count in row #{index} (#{@data.first.size} expected, but has #{row.size})" if @data.first && row.size != @data.first.size raise ArgumentError, "Row must be provided as Array, but got #{row.class} in row #{index}" unless row.is_a?(Array) @data << row @rows << Row.new(self, index, row) self end |
#[](*args) ⇒ Array<TableData::Row>
Array#[] like access to the rows in the body of the table.
107 108 109 |
# File 'lib/tabledata/table.rb', line 107 def [](*args) body[*args] end |
#accessors? ⇒ Boolean
158 159 160 |
# File 'lib/tabledata/table.rb', line 158 def accessors? !@accessors.empty? end |
#body ⇒ Object
170 171 172 |
# File 'lib/tabledata/table.rb', line 170 def body headers? ? @rows[1..-1] : @rows end |
#cell(row, column, default = nil) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/tabledata/table.rb', line 111 def cell(row, column, default=nil) row_data = row(row) if row_data row_data.at(column) elsif block_given? yield(self, row, column) else default end end |
#column(index) ⇒ Object
141 142 143 |
# File 'lib/tabledata/table.rb', line 141 def column(index) Column.new(self, index) end |
#column_accessor(index) ⇒ Object
127 128 129 |
# File 'lib/tabledata/table.rb', line 127 def column_accessor(index) @column_accessors[index] end |
#column_count ⇒ Integer
Returns The number of columns.
100 101 102 |
# File 'lib/tabledata/table.rb', line 100 def column_count @data.first ? @data.first.size : 0 end |
#column_name(index) ⇒ Object
131 132 133 134 135 |
# File 'lib/tabledata/table.rb', line 131 def column_name(index) h = headers h && h.at(index) end |
#columns ⇒ Object
137 138 139 |
# File 'lib/tabledata/table.rb', line 137 def columns Array.new(column_count) { |col| column(col) } end |
#each {|row| ... } ⇒ self
Iterate over all rows in the body
194 195 196 197 198 199 200 |
# File 'lib/tabledata/table.rb', line 194 def each(&block) return enum_for(__method__) unless block body.each(&block) self end |
#each_column {|column| ... } ⇒ self
Iterate over all columns
224 225 226 227 228 229 230 231 232 |
# File 'lib/tabledata/table.rb', line 224 def each_column return enum_for(__method__) unless block column_count.times do |i| yield column(i) end self end |
#each_row {|row| ... } ⇒ self
Iterate over all rows, header and body
210 211 212 213 214 215 216 |
# File 'lib/tabledata/table.rb', line 210 def each_row(&block) return enum_for(__method__) unless block @data.each(&block) self end |
#format(format_id, options = nil) ⇒ Object
242 243 244 |
# File 'lib/tabledata/table.rb', line 242 def format(format_id, =nil) Presenter.present(self, format_id, ) end |
#headers ⇒ Object
166 167 168 |
# File 'lib/tabledata/table.rb', line 166 def headers headers? ? @rows.first : nil end |
#headers? ⇒ Boolean
162 163 164 |
# File 'lib/tabledata/table.rb', line 162 def headers? @has_header end |
#index_for_accessor(name) ⇒ Object
145 146 147 |
# File 'lib/tabledata/table.rb', line 145 def index_for_accessor(name) @accessor_columns[name.to_sym] end |
#index_for_header(name) ⇒ Object
149 150 151 152 153 154 155 156 |
# File 'lib/tabledata/table.rb', line 149 def index_for_header(name) if @has_header && @data.first then @header_columns ||= Hash[@data.first.each_with_index.to_a] @header_columns[name] else nil end end |
#inspect ⇒ Object
246 247 248 |
# File 'lib/tabledata/table.rb', line 246 def inspect sprintf "#<%s headers: %p, cols: %d, rows: %d>", self.class, headers?, column_count, size end |
#row(row) ⇒ Object
123 124 125 |
# File 'lib/tabledata/table.rb', line 123 def row(row) @rows[row] end |
#size ⇒ Object Also known as: length
The number of rows, excluding headers
94 95 96 |
# File 'lib/tabledata/table.rb', line 94 def size @data.size - (@has_header ? 1 : 0) end |
#to_a ⇒ Object
238 239 240 |
# File 'lib/tabledata/table.rb', line 238 def to_a @data end |
#to_nested_array ⇒ Object
234 235 236 |
# File 'lib/tabledata/table.rb', line 234 def to_nested_array to_a.map(&:to_a) end |