Rails CSV удалить столбец с пустым заголовком

Я получаю CSV-файл с пустыми заголовками, но в этих столбцах есть данные. Я хочу удалить пустой заголовок и связанный с ним столбец в рельсах.

Образец CSV

#report
,Code,Price,Orders,,Mark,
1,X91,4.55,4,xxx,F,23

Что я хотел бы вернуть:

Code,Price,Orders,Mark
A91,4.55,4,F

Это то, что у меня есть, поскольку есть также комментарии к CSV, который я игнорирую.

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 ответа


Вы можете использовать метод CSV :: Row delete_if https://ruby-doc.org/stdlib-2.4.1/libdoc/csv/rdoc/CSV/Row.html#method-i-delete_if , что-то вроде:

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

Хотя я в значительной степени согласен с ответом arieljuod , есть несколько вещей, которые могут пойти не так. row.header_row? всегда будет возвращать false , поскольку return_headers: true не установлена, поэтому заголовок не будет return_headers: true . row.delete_if является методом мутации, поэтому нет необходимости сохранять результат в переменной. Это только само по себе, так что вы можете связать его с другими методами.

Следующего будет достаточно:

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

Обратите внимание, что blank? это метод Ruby on Rails, но так как вы пометили вопрос с помощью ruby-on-rails, это будет хорошо.

Из параметров CSV::new документация (также описывающая CSV::foreach ):

: return_headers

Когда false , строки заголовка молча проглатываются. Если установлено значение true , строки заголовка возвращаются в объекте CSV :: Row с одинаковыми заголовками и полями (за исключением того, что поля не проходят через конвертеры).


Есть идеи?

10000