Class: Eco::CSV::Table

Inherits:
CSV::Table
  • Object
show all
Defined in:
lib/eco/csv/table.rb

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Table

Returns a new instance of Table.

Parameters:

  • input (Array<Row>, Array<Array>, Eco::CSV::Table, ::CSV::Table)
    • when Array<Array> => all rows as arrays where first array is the header


6
7
8
9
10
11
12
# File 'lib/eco/csv/table.rb', line 6

def initialize(input)
  super(to_rows_array(input))
  self.delete_if do |row|
    values = row.fields
    values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
  end
end

Instance Method Details

#add_column(header_name) ⇒ Eco::CSV::Table

Adds a new column at the end

Parameters:

  • header_name (String)

    header of the new column

Returns:



116
117
118
119
# File 'lib/eco/csv/table.rb', line 116

def add_column(header_name)
  new_col = Array.new(length).unshift(header_name)
  columns_to_table(columns.push(new_col))
end

#columnsArray<Array>

Returns each array is the column header followed by its values.

Returns:

  • (Array<Array>)

    each array is the column header followed by its values



157
158
159
# File 'lib/eco/csv/table.rb', line 157

def columns
  to_a.transpose
end

#columns_hashHash

Note:

it will override columns with same header name

Creates a single Hash where each key, value is a column (header + values)

Returns:

  • (Hash)

    keys are headers, values are arrays



164
165
166
167
168
# File 'lib/eco/csv/table.rb', line 164

def columns_hash
  columns.map do |col|
    [col.first, col[1..-1]]
  end.to_h
end

#delete_column(i) ⇒ Eco::CSV::Table

Returns:



107
108
109
110
111
# File 'lib/eco/csv/table.rb', line 107

def delete_column(i)
  csv_cols = columns
  csv_cols.delete(i)
  columns_to_table(csv_cols)
end

#delete_duplicates!Object

It removes all rows where all columns' values are the same



129
130
131
132
133
134
135
136
# File 'lib/eco/csv/table.rb', line 129

def delete_duplicates!
  unique_rows = []
  self.by_row!.delete_if do |row|
    unique_rows.any? {|done| equal_rows?(row, done)}.tap do |found|
      unique_rows << row unless found
    end
  end
end

#duplicated_header_namesArray<String>

Returns list of duplicated header names.

Returns:

  • (Array<String>)

    list of duplicated header names



59
60
61
62
# File 'lib/eco/csv/table.rb', line 59

def duplicated_header_names
  header = self.headers
  header.select {|e| header.count(e) > 1}.uniq
end

#empty?Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/eco/csv/table.rb', line 152

def empty?
  length < 1
end

#equal_rows?(row1, row2) ⇒ Boolean

Parameters:

  • row1 (CSV:Row)

    row to be compared

  • row2 (CSV:Row)

    row to be compared

  • `true` (Boolean)

    if all values of row1 are as of row2

Returns:

  • (Boolean)


141
142
143
144
145
# File 'lib/eco/csv/table.rb', line 141

def equal_rows?(row1, row2)
  row1.fields.zip(row2.fields).all? do |(v1, v2)|
    v1 == v2
  end
end

#group_by(&block) ⇒ Hash

Returns where keys are the groups and the values a Eco::CSV::Table.

Returns:

  • (Hash)

    where keys are the groups and the values a Eco::CSV::Table



15
16
17
18
19
# File 'lib/eco/csv/table.rb', line 15

def group_by(&block)
  rows.group_by(&block).transform_values do |rows|
    self.class.new(rows)
  end
end

#lengthInteger

Returns total number of rows not including the header.

Returns:

  • (Integer)

    total number of rows not including the header



148
149
150
# File 'lib/eco/csv/table.rb', line 148

def length
  to_a.length - 1
end

#merge_same_header_namesEco::CSV::Table

Note:

it also offers a way to resolve merge conflicts

When there are headers with the same name, it merges those columns

Returns:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/eco/csv/table.rb', line 35

def merge_same_header_names
  dups = self.duplicated_header_names
  out_rows = self.map do |row|
    row.to_a.each_with_object({}) do |(name, value), out|
      if dups.include?(name) && out.key?(name)
        if block_given?
          yield(value, out[name], name)
        else
          # resolve
          value || out[name]
        end
      elsif out.key?(name)
        out[name]
      else
        value
      end.tap do |final_value|
        out[name] = final_value
      end
    end
  end
  self.class.new(out_rows)
end

#rowsArray<::CSV::Row>

Returns:

  • (Array<::CSV::Row>)


122
123
124
125
126
# File 'lib/eco/csv/table.rb', line 122

def rows
  [].tap do |out|
    self.each {|row| out << row}
  end
end

#slice(*index) ⇒ Eco::CSV::Table

Slices the selected rows

Returns:



80
81
82
83
84
85
86
87
# File 'lib/eco/csv/table.rb', line 80

def slice(*index)
  case index.first
  when Range, Numeric
    self.class.new(rows.slice(index.first))
  else
    self
  end
end

#slice_columns(*index) ⇒ Eco::CSV::Table

Returns:



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

def slice_columns(*index)
  case index.first
  when Range, Numeric
    columns_to_table(columns.slice(index.first))
  when String
    csv_cols = columns
    csv_cols = index.each_with_object([]) do |name, cols|
      col = csv_cols.find {|col| col.first == name}
      cols << col if col
    end
    columns_to_table(csv_cols)
  else
    self
  end
end

#to_a_hObject

Note:

it will override columns with same header

Returns an array of row hashes



172
173
174
# File 'lib/eco/csv/table.rb', line 172

def to_a_h
  rows.map(&:to_h)
end

#to_array_of_hashesObject

See Also:



177
178
179
# File 'lib/eco/csv/table.rb', line 177

def to_array_of_hashes
  to_a_h
end

#transform_headersEco::CSV::Table

It allows to rename the header names

Returns:



23
24
25
26
27
28
29
30
# File 'lib/eco/csv/table.rb', line 23

def transform_headers
  header = self.headers
  cols   = self.columns
  cols.each do |col|
    col[0] = yield(col.first)
  end
  columns_to_table(cols)
end

#transform_valuesEco::CSV::Table

Returns:



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/eco/csv/table.rb', line 65

def transform_values
  transformed_rows = rows.map do |row|
    res = yield(row)
    case res
    when Array
      ::CSV::Row.new(row.headers, res)
    when ::CSV::Row
      res
    end
  end
  self.class.new(transformed_rows)
end