spuder
spuder

Reputation: 18467

How to replace CSV headers

If using the 'csv' library in ruby, how would you replace the headers without re-reading in a file?

foo.csv

'date','foo',bar'
1,2,3
4,5,6

Using a CSV::Table because of this answer

Here is a working solution, however it requires writing and reading from a file twice.

require 'csv'
@csv = CSV.table('foo.csv')

# Perform additional operations, like remove specific pieces of information. 

# Save fixed csv to a file (with incorrect headers)
File.open('bar.csv','w') do |f|
  f.write(@csv.to_csv)
end

# New headers
new_keywords = ['dur','hur', 'whur']

# Reopen the file, replace the headers, and print it out for debugging
# Not sure how to replace the headers of a CSV::Table object, however I *can* replace the headers of an array of arrays (hence the file.open)
lines = File.readlines('bar.csv')
lines.shift
lines.unshift(new_keywords.join(',') + "\n")
puts lines.join('')

# TODO: re-save file to disk

How could I modify the headers without reading from disk twice?

'dur','hur','whur'
1,x,3
4,5,x

Update
For those curious, here is the unabridged code. In order to use things like delete_if() the CSV must be imported with the CSV.table() function.

Perhaps the headers could be changed by converting the csv table into an array of arrays, however I'm not sure how to do that.

Upvotes: 0

Views: 752

Answers (1)

Travis Hohl
Travis Hohl

Reputation: 2196

Given a test.csv file whose contents look like this:

id,name,age
1,jack,8
2,jill,9

You can replace the header row using this:

require 'csv'

array_of_arrays = CSV.read('test.csv')

p array_of_arrays # => [["id", "name", "age"],
                  # =>  ["1", "jack", "26"],
                  # =>  ["2", "jill", "27"]]    

new_keywords = ['dur','hur','whur']

array_of_arrays[0] = new_keywords

p array_of_arrays # => [["dur", "hur", "whur"],
                  # =>  ["1", " jack", " 26"],
                  # =>  ["2", " jill", " 27"]]

Or if you'd rather preserve your original two-dimensional array:

new_array = Array.new(array_of_arrays)
new_array[0] = new_keywords

p new_array # => [["dur", "hur", "whur"],
            # =>  ["1", " jack", " 26"],
            # =>  ["2", " jill", " 27"]]

p array_of_arrays # => [["id", "name", "age"],
                  # =>  ["1", "jack", "26"],
                  # =>  ["2", "jill", "27"]]

Upvotes: 1

Related Questions