Reputation: 343
I am receiving a csv file that has some blank headers but data exists in these columns. I want to remove the blank header and it's associated column in rails.
Sample csv
#report
,Code,Price,Orders,,Mark,
1,X91,4.55,4,xxx,F,23
What I'd like returned:
Code,Price,Orders,Mark
A91,4.55,4,F
This is what I have so far as there is also comments on the csv which i am ignoring.
CSV.open("output.csv", "w") do |output_csv|
CSV.foreach("out.csv", encoding: "bom|utf-8", skip_lines: /^#/, headers: true).with_index(0) do |row, i|
output_csv << row.headers if i == 0
output_csv << row
end
end
Upvotes: 0
Views: 1146
Reputation: 21130
Although I largely agree with the answer of arieljuod, there are a few things that might go wrong. row.header_row?
will always return false
, since the return_headers: true
option isn't set, thus leaving out the header. delete_if
is a mutating method, so there is no need to save the result in a variable. This only returns itself so you can chain it with other methods.
The following would be enough:
read_options = {
encoding: "bom|utf-8",
skip_lines: /^#/,
headers: true,
return_headers: true,
}
CSV.open("output.csv", "w") do |output_csv|
CSV.foreach("out.csv", read_options) do |row|
row.delete_if { |header, _field| header.blank? }
output_csv << row
end
end
Note that blank?
is a Ruby on Rails method, but since you've tagged the question with ruby-on-rails this should be fine.
From the CSV::new
documentation (also describing CSV::foreach
) options:
:return_headers
When
false
, header rows are silently swallowed. If set totrue
, header rows are returned in a CSV::Row object with identical headers and fields (save that the fields do not go through the converters).
Upvotes: 2
Reputation: 15838
You can use CSV::Row's delete_if
method https://ruby-doc.org/stdlib-2.4.1/libdoc/csv/rdoc/CSV/Row.html#method-i-delete_if, something like:
CSV.open("output.csv", "w") do |output_csv|
CSV.foreach("out.csv", encoding: "bom|utf-8", skip_lines: /^#/, headers: true) do |row|
clean_row = row.delete_if { |header, _field| header.blank? }
output_csv << clean_row.headers if row.header_row?
output_csv << clean_row
end
end
Upvotes: 3