Class: FastererCSV::Table

Inherits:
Array
  • Object
show all
Defined in:
lib/fasterer_csv.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(headers, fail_on_malformed_columns = true, &line_block) ⇒ Table

Returns a new instance of Table.



16
17
18
19
20
21
22
# File 'lib/fasterer_csv.rb', line 16

def initialize(headers, fail_on_malformed_columns = true, &line_block)
  @headers = Table.format_headers(headers)
  @fail_on_malformed_columns = fail_on_malformed_columns
  @line_block = line_block
  @lines = 0
  @indexes = {}
end

Instance Attribute Details

#headersObject (readonly)

Returns the value of attribute headers.



14
15
16
# File 'lib/fasterer_csv.rb', line 14

def headers
  @headers
end

#line_blockObject (readonly)

Returns the value of attribute line_block.



14
15
16
# File 'lib/fasterer_csv.rb', line 14

def line_block
  @line_block
end

#linesObject (readonly)

Returns the value of attribute lines.



14
15
16
# File 'lib/fasterer_csv.rb', line 14

def lines
  @lines
end

Class Method Details

.format_headers(unformatted) ⇒ Object



9
10
11
# File 'lib/fasterer_csv.rb', line 9

def format_headers(unformatted)
  unformatted.map { |header| Row.to_key(header) }
end

Instance Method Details

#<<(row) ⇒ Object Also known as: push



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/fasterer_csv.rb', line 24

def <<(row)
  @lines += 1
  if !row.is_a?(Row)
    row = Row.new(self, row, @lines)
  end
  if @headers.length != row.length
    error = "*** WARNING - COLUMN COUNT MISMATCH - WARNING ***\n*** ROW #{size} : EXPECTED #{@headers.length} : FOUND #{row.length}\n\n"
    len = 0
    headers.each do |header|
      len = header.to_s.length if header.to_s.length > len
    end
    headers.each_with_index do |header, i|
      error << sprintf("%-32s : %s\n", header, row[i])
    end
    puts error
    raise error if @fail_on_malformed_columns
  end
  if line_block
    line_block.call(row)
  else
    super(row)
  end
end

#index(columns, reindex = false) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/fasterer_csv.rb', line 69

def index(columns, reindex = false)
  columns = columns.compact.uniq.sort { |a, b| a.to_s <=> b.to_s }.map { |column| Row.to_key(column) }

  key = columns.join('|#|')

  @indexes[key] ||= {}

  index = @indexes[key]

  if reindex || index.empty?

    self.each do |row|
      vkey = columns.map { |column| row[column] }
      index[vkey] ||= []
      index[vkey] << row
    end
  end
  index
end

#lookup(key) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/fasterer_csv.rb', line 89

def lookup(key)

  values  = []
  columns = key.keys.compact.uniq.sort { |a, b| a.to_s <=> b.to_s }.map do |column|
    values << key[column]
    Row.to_key(column)
  end

  rows = index(columns)[values]
  if rows && block_given?
    rows.each do |row|
      yield(row)
    end
  end

  rows
end

#merge(*tables) ⇒ Object Also known as: merge!



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/fasterer_csv.rb', line 49

def merge(*tables)

  tables.each do |table|
    matching = self.headers & table.headers

    key = {}

    table.each do |row|
      matching.each do |match|
        key[match] = row[match]
      end

      self.lookup(key) { |r| r.merge(row) }
    end
  end

  self

end

#write(file, quot = '~', sep = ',') ⇒ Object



107
108
109
110
111
112
113
114
# File 'lib/fasterer_csv.rb', line 107

def write(file, quot = '~', sep = ',')
  FastererCSV.write(file, quot, sep) do |out|
    out << headers
    each do |row|
      out << row
    end
  end
end