Как получить заголовки из файла CSV в рубине

Мне нужно проверить заголовки в CSV файле перед анализом данных в нем.

# convert the data into an array of hashes
CSV::Converters[:blank_to_nil] = lambda do |field|
  field && field.empty? ? nil : field
end
csv = CSV.new(file, :headers => true, :header_converters => :symbol, :converters => [:all, :blank_to_nil])
csv_data = csv.to_a.map {|row| row.to_hash }

Я знаю, что могу использовать метод заголовков для получения заголовков

    headers = csv.headers

Но проблема с метод заголовков заключается в том, что он возвращает "нет", если заголовки не будут использоваться, правда, если они будут, но еще не прочитаны, или фактические заголовки после того, как они были прочитаны. "

Итак, если я помещаю headers = csv.headers выше csv_data = csv.to_a.map {|row| row.to_hash }, строка headers равна true, и если я поместил ее после чтения данных, headers содержит строку заголовков в массиве. Он накладывает порядок инструкций по моему методу, который очень трудно проверить и плохо программирует.

Есть ли способ прочитать строку заголовков без наложения порядка в этом сценарии? Я использую ruby ​​2.0.

Ответ 1

CSV.open(file_path, &:readline)

Ответ 2

У меня проблема! У меня такой же. Вызов read, кажется, делает то, что вы хотите (заполняет переменную headers):

data = CSV.new(file, **flags)
data.headers # => true

data = CSV.new(file, **flags).read
data.headers # => ['field1', 'field2']

Могут быть другие побочные эффекты, о которых я не знаю, но это работает для меня и плохо пахнет.

Ответ 3

Я не совсем понимаю проблему. Если вы используете один из методов итератора, довольно легко сделать некоторую проверку в заголовках:

CSV.foreach('tmp.txt', headers: true) do |csv| 
  return unless csv.headers[0] != 'xyz'
end