Module: CsvMadness::SheetMethods::ColumnMethods

Included in:
CsvMadness::Sheet
Defined in:
lib/csv_madness/sheet_methods/column_methods.rb

Constant Summary collapse

COLUMN_TYPES =
{
  number: Proc.new do |cell, record|
    rval = cell
  
    unless cell.nil? || (cell.is_a?(String) && cell.length == 0)
  
      begin
        rval = Integer(cell)
      rescue
        # do nothing
      end
  
      unless rval.is_a?(Integer)
        begin
          rval = Float(cell)
        rescue
          # do nothing
        end
      end
    end
  
    rval
  end,

  integer: Proc.new do |cell, record|
    begin
      Integer(cell)
    rescue
      cell
    end
  end,

  float:   Proc.new do |cell, record|
    begin
      Float(cell)
    rescue
      cell
    end
  end,

  date:    Proc.new do |cell, record|
    begin
      parse = Time.parse( cell || "" )
    rescue ArgumentError
      if cell =~ /^Invalid Time Format: /
        parse = cell
      else
        parse = "Invalid Time Format: <#{cell}>"
      end
    end
  
    parse
  end
}
FORBIDDEN_COLUMN_NAMES =

breaks things hard when you use them. Probably not comprehensive, sadly.

[:to_s]

Instance Method Summary collapse

Instance Method Details

#add_column(column, &block) ⇒ Object

If no block given, adds an empty column. If block given, fills the new column cells when the block is run on each record TODO: Should be able to specify the index of the column

Raises:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 97

def add_column( column, &block )
  raise_on_forbidden_column_names( column )
  raise ColumnExistsError.new( "Column already exists: #{column}" ) if @columns.include?( column )

  @columns << column

  # add empty column to each row
  @records.map{ |r|
    r.csv_data << {column => ""} 
  }

  update_data_accessor_module

  if block_given?
    alter_column( column ) do |val, record|
      yield val, record
    end
  end
end

#alter_column(column, blank = :undefined, &block) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 80

def alter_column( column, blank = :undefined, &block )
  raise_on_missing_columns( column )

  if cindex = @columns.index( column )
    for record in @records
      if record.blank?(column) && blank != :undefined
        record[cindex] = blank
      else
        record[cindex] = yield( record[cindex], record )
      end
    end
  end
end

#column(col) ⇒ Object



63
64
65
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 63

def column col
  @records.map(&col)
end

#concat_columns(col1, col2, opts = {}) ⇒ Object Also known as: concatenate

By default, the



157
158
159
160
161
162
163
164
165
166
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 157

def concat_columns( col1, col2, opts = {} )
  opts =  {:separator => '', :out => col1}.merge( opts )

  raise_on_missing_columns( col1, col2 )
  self.add_column( opts[:out] ) unless self.columns.include?( opts[:out] )

  for record in self.records
    record[ opts[:out] ] = "#{record[col1]}#{opts[:separator]}#{record[col2]}"
  end
end

#drop_column(column) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 117

def drop_column( column )
  raise_on_missing_columns( column )

  @columns.delete( column )

  key = column.to_s

  @records.map{ |r|
    r.csv_data.delete( key )
  }

  update_data_accessor_module
end

#has_column?(col) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 67

def has_column?( col )
  self.columns.include?( col.to_sym )
end

#merge_columns(source, dest, opts = {}) ⇒ Object

If :reverse_merge is true, then the dest column is only overwritten for records where :dest is blank



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 143

def merge_columns( source, dest, opts = {} )
  opts = { :drop_source => true, :reverse_merge => false, :default => "" }.merge( opts )
  raise_on_missing_columns( source, dest )

  self.records.each do |record|
    if opts[:reverse_merge] == false || record.blank?( dest )
      record[dest] = record.blank?(source) ? opts[:default] : record[source]
    end
  end

  self.drop_column( source ) if opts[:drop_source]
end

#multiple_columns(*args) ⇒ Object

retrieve multiple columns. Returns an array of the form [ [record1:col1, record1:col2...], [record2:col1, record2:col2...] [...] ]



73
74
75
76
77
78
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 73

def multiple_columns(*args)
  @records.inject([]){ |memo, record|
    memo << args.map{ |arg| record.send(arg) }
    memo
  }
end

#rename_column(column, new_name) ⇒ Object



131
132
133
134
135
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 131

def rename_column( column, new_name )
  @columns[@columns.index(column)] = new_name
  rename_index_column( column, new_name ) if @index_columns.include?( column )
  update_data_accessor_module
end

#set_column_type(column, type, blank = :undefined) ⇒ Object



137
138
139
# File 'lib/csv_madness/sheet_methods/column_methods.rb', line 137

def set_column_type( column, type, blank = :undefined )
  alter_column( column, blank, &COLUMN_TYPES[type] )
end