0

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

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

Comments

2

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 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 to true, header rows are returned in a CSV::Row object with identical headers and fields (save that the fields do not go through the converters).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.