Skip to content

Instantly share code, notes, and snippets.

@ktaragorn
Last active January 17, 2017 03:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ktaragorn/9b856cdc5bed7199733d72aed2f446ce to your computer and use it in GitHub Desktop.
Save ktaragorn/9b856cdc5bed7199733d72aed2f446ce to your computer and use it in GitHub Desktop.
Simple script that lets you add table view to any irb - just copy paste and use with `table <list of arrays or hashable objects>`. `htable` works the same as `table`, but generates a horizontal table.
def get_columns list, options = {}
all = list.map{|item| item.columns}.flatten.uniq
symize = ->(key){key.try(:to_sym) || key}
if options[:only]
Array(options[:only]).map(&symize) & all
elsif options[:keys_search]
all.select{|k| k.to_s.downcase.match(options[:keys_search].to_s.downcase)}
else
all - Array(options[:not]).map(&symize)
end
end
class TablePrinter
def initialize options= {}
@lines_to_print = []
@horizontal = options[:horizontal]
@truncate = options[:truncate] || 20
end
def add_line items
@lines_to_print << items.map(&:to_s).map{|s| s.truncate(@truncate + 3)}
end
def add_header columns
add_line columns
add_line ["_"]* columns.count
end
def add_data data, columns
add_line columns.map{|col| data.fetch(col)}
end
def print_all
@lines_to_print = @lines_to_print.transpose if @horizontal
max_width = []
@lines_to_print.each do |line|
line.each_with_index do |col_val, index|
if (max_width[index]||0)< col_val.size
max_width[index] = col_val.size
end
end
end
@lines_to_print.each do |line|
line.each_with_index do |item, index|
print item.rjust(max_width[index])
print "|"
end
print "\n"
end
end
end
class Item
def fetch col
_fetch(col).to_s
end
def has? query
_values.any? {|val| val.to_s.downcase.match(query.to_s.downcase)}
end
end
class ArrayItem < Item
def initialize item
@item = Array.wrap(item)
end
def _fetch col
@item[col.try(:to_i)]
end
def _values
@item
end
def columns
(0..@item.size).to_a
end
end
class HashItem < Item
def initialize(item)
@item = item.to_hash.symbolize_keys
end
def _fetch col
@item[col.to_sym]
end
def _values
@item.values
end
def columns
@item.keys
end
end
def _wrap_item(item)
item.respond_to?(:to_hash) ? HashItem.new(item) : ArrayItem.new(item)
end
def _gather_data printer, list, options = {}
list = Array.wrap(list).map{|item| _wrap_item(item)}
columns = get_columns(list, options)
printer.add_header columns
list.select!{|item| item.has? options[:search]} if options[:search]
list.sort_by!{|item| item.fetch options[:sort]} if options[:sort]
list.each do |data|
printer.add_data data, columns
end
end
def table list, options = {}
printer = TablePrinter.new truncate: options[:truncate]
_gather_data printer, list, options
printer.print_all
nil
end
def htable list, options = {}
printer = TablePrinter.new horizontal: true, truncate: options[:truncate]
_gather_data printer, list, options
printer.print_all
nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment