class TrueTable
Public Class Methods
Loads a CSV string
@example
csv = "id,name\n1,Harry\n2,Lloyd" table = TrueTable.load_csv csv, converters: [:date, :numeric]
@param [String] csv_string CSV string. @param [Hash] options options to forward to the CSV class.
@return [TrueTable] the new table object
# File lib/true_table.rb, line 15 def from_csv(csv_string, options = {}) default_options = { headers: true, converters: :numeric, header_converters: :symbol } csv = CSV.new csv_string, **default_options.merge(options) new.tap do |table| csv.each { |row| table << row.to_h } end end
Loads a CSV file
@example
table = TrueTable.from_csv "sample.csv", converters: [:date, :numeric]
@param [String] path the path to the CSV file. @param [Hash] options options to forward to the CSV class.
@return [TrueTable] the new table object
# File lib/true_table.rb, line 32 def load_csv(path, options = {}) from_csv File.read(path), options end
Public Instance Methods
Combines table with other and returns a new one
# File lib/true_table.rb, line 38 def +(other) result = self.class.new each_row { |row, i| result << row.merge(other[i]) } result end
Returns a new table without the specified columns
# File lib/true_table.rb, line 45 def -(cols) keep_keys = headers - cols result = self.class.new each_row { |row, i| result << row.slice(*keep_keys) } result end
Returns a row or a column
# File lib/true_table.rb, line 53 def [](key) key.is_a?(Symbol) ? col(key) : super end
Adds or updates a row or a column
# File lib/true_table.rb, line 58 def []=(key, value) key.is_a?(Symbol) ? add_col(key.to_sym, value) : super end
Returns a deep copy of self
# File lib/true_table.rb, line 63 def clone self.class.new map(&:clone) end
Returns a column as Array
# File lib/true_table.rb, line 68 def col(key) map { |row| row[key] } end
Returns a hash of columns
# File lib/true_table.rb, line 73 def cols result = {} each_col { |col, header| result[header] = col } result end
Returns a copy of self without rows that contain nil in any column
# File lib/true_table.rb, line 80 def compact dup.compact! end
Removes rows with nil in any column
# File lib/true_table.rb, line 85 def compact! delete_if { |row| row.values.include? nil } end
Delete a row or a column in place and returns the deleted row/column
# File lib/true_table.rb, line 90 def delete_at(index) if index.is_a?(Symbol) || index.is_a?(String) result = self[index] return nil unless result each_row { |row, i| row.delete index } result else super end end
Returns a table with different rows
# File lib/true_table.rb, line 104 def difference(*others) self.class.new super end
Extracts nested value. Accepts row, column or column, row
# File lib/true_table.rb, line 109 def dig(*indexes) key = indexes.shift if key.is_a?(Symbol) col(key.to_sym).dig *indexes else row(key).dig *indexes end end
Returns a new table without the first N rows
# File lib/true_table.rb, line 119 def drop(*args) self.class.new super end
Returns a new table with rows until the block returns false
# File lib/true_table.rb, line 124 def drop_while(*args) self.class.new super end
Iterates over columns
# File lib/true_table.rb, line 129 def each_col headers.each { |header| yield col(header), header } end
# File lib/true_table.rb, line 136 def fetch(key, *default) if key.is_a?(Symbol) if headers.include? key col(key.to_sym) elsif default.any? default.first elsif block_given? yield key else raise IndexError, "row :#{key} does not exist" end else super end end
Returns an array of column headers
# File lib/true_table.rb, line 153 def headers first.keys end
Returns a new table with intersecting rows
# File lib/true_table.rb, line 158 def intersection(*others) self.class.new super end
Returns a string with joined rows and columns
# File lib/true_table.rb, line 163 def join(row_separator = $,, col_separator = nil, with_headers: false) if col_separator result = map { |row| row.values.join col_separator }.join(row_separator) with_headers ? headers.join(col_separator) + row_separator + result : result else super row_separator end end
Returns the last row or a new table with the last N rows
# File lib/true_table.rb, line 173 def last(*args) args.empty? ? super : self.class.new(super) end
Returns a new table without rejected rows
# File lib/true_table.rb, line 178 def reject self.class.new super end
Returns a reversed copy
# File lib/true_table.rb, line 183 def reverse self.class.new super end
Returns a new table with the element at `count` as the first element
# File lib/true_table.rb, line 188 def rotate(count = 1) self.class.new super end
Saves the table as a CSV file
# File lib/true_table.rb, line 196 def save_csv(path) File.write path, to_csv end
Returns a new table with selected rows
# File lib/true_table.rb, line 201 def select self.class.new super end
Returns a new shuffled tables
# File lib/true_table.rb, line 207 def shuffle(*args) self.class.new super end
Returns a new table slice
# File lib/true_table.rb, line 212 def slice(*args) if args.count == 1 and args.first.is_a? Integer super else self.class.new super end end
Deletes and returns one more rows
# File lib/true_table.rb, line 221 def slice!(*args) if args.count == 1 and args.first.is_a? Integer super else self.class.new super end end
Returns a new sorted table
# File lib/true_table.rb, line 230 def sort self.class.new super end
Returns a new sorted table
# File lib/true_table.rb, line 235 def sort_by self.class.new super end
Returns a new table with the first N rows
# File lib/true_table.rb, line 240 def take(*args) self.class.new super end
Returns a new table with rows until the block returns false
# File lib/true_table.rb, line 245 def take_while(*args) self.class.new super end
Returns a CSV string
# File lib/true_table.rb, line 250 def to_csv(row_separator = "\n", col_separator = ",") join(row_separator, col_separator, with_headers: true) end
Returns a hash representation of the table using the values of the first column as hash keys
# File lib/true_table.rb, line 256 def to_h map { |row| [row.values.first, row] }.to_h end
Returns only values, without any headers (array of arrays)
# File lib/true_table.rb, line 261 def values map { |row| row.values } end
Protected Instance Methods
# File lib/true_table.rb, line 267 def add_col(key, values) values.each_with_index do |value, i| self[i] ||= {} self[i][key] = value end end