Consider a CSV file like below. I would like to change the Credit/Debit field to 0 if they are empty strings and then do some processing.
The roundabout way that I came up with seems inefficient since I read in the csv file, apply the converter and then convert it to CSV::Table for processing. Is there a way to directly apply the converter to parse method ?
For example:
csv_data = <<_
Description,Debit,Credit
Eating Out,10,""
_
csv = CSV.new(csv_data, headers: true, converters: :integer)
csv.convert do |field, info|
if info.index == 1
field == "" ? 0 : field
end
if info.index == 2
field == "" ? 0 : field
end
end
table = CSV::Table.new(csv.to_a) #Seems wrong to convert to array
puts table[0]['Debit'] #10
puts table[0]['Credit'] #0
You can pass the same options to parse that you can pass to new, and with new you can pass in an array of converters, which can be the name of one of the built-in converters, or a lambda:
table = CSV.parse(csv_data, headers: true, converters: [
:integer,
-> field, info { 'Credit' == info.header && field.empty? ? 0 : field },
-> field, info { 'Debit' == info.header && field.empty? ? 0 : field },
])
p table # => #<CSV::Table mode:col_or_row row_count:2>
puts table[0]['Debit'] # => 10
puts table[0]['Credit'] # => 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With