Skip to content

Instantly share code, notes, and snippets.

@pelly
Created October 13, 2016 22:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pelly/2e523210f744bcf70475b3b1f9648621 to your computer and use it in GitHub Desktop.
Save pelly/2e523210f744bcf70475b3b1f9648621 to your computer and use it in GitHub Desktop.
data table wrapper
class DataTable
include Enumerable
class Row
def initialize(headers_index: headers_index, row: row)
@headers_index = headers_index
@row = row
end
def [](name)
@row[@headers_index[name]]
end
def []=(name, value)
@row[@headers_index[name]] = value
end
def values
@row
end
def to_hash
inverted_index = @headers_index.invert
counter = 0
(0...@row.length).inject({}) { |a, idx|
header = inverted_index[idx] || "missing"
while a.has_key?(header)
counter += 1
header = "#{header}.#{counter}"
end
a[header] = @row[idx]
a
}
end
end
attr_reader :headers
def initialize(headers:[], rows:[])
@rows = rows
self.headers=headers
end
class Wrapper
def initialize(table:)
@table = table
end
[:sort_by, :map].each do |method|
class_eval <<-EOM
def #{method}(*args, &block)
DataTable.new(headers: @table.headers, rows: @table.#{method}(*args, &block))
end
EOM
end
end
def wrap
Wrapper.new(table: self)
end
def <<(row)
@rows << row
end
def [](idx)
Row.new(headers_index: @headers_index, row: @rows[idx])
end
def length
@rows.length
end
# def join(other)
# lesser, greater = self.length < other.length ? [self, other] : [other, self]
# self.
# self.select
def headers=(headers)
@headers = headers.dup
reindex_headers
end
def reindex_headers
@headers_index = Hash[@headers.each_with_index.map {|h,idx| [h, idx]}]
end
def each
@rows.each do |row|
yield(Row.new(headers_index: @headers_index, row: row))
end
end
def output
Output.aligned_table([headers] + @rows )
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment