Я получаю 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 с одинаковыми заголовками и полями (за исключением того, что поля не проходят через конвертеры).