如何从ruby中的CSV文件中获取标头

时间:2014-01-12 18:25:54

标签: ruby-on-rails ruby

我需要在解析数据之前验证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 }

我知道我可以使用header方法来获取标题

    headers = csv.headers

但问题headers method是"如果不使用标题则返回nil,如果它们尚未被读取则返回true,或者在读取之后返回实际标题。&# 34;

因此,如果我将headers = csv.headers放在csv_data = csv.to_a.map {|row| row.to_hash }headers上方true,如果我在读取数据后将其放入,headers包含数组中的标题行。它对我的方法施加了一个指令顺序,这个指令非常难以测试并且编程很糟糕。

在这种情况下,有没有办法在不强加顺序的情况下读取标题行?我使用的是ruby 2.0。

3 个答案:

答案 0 :(得分:15)

CSV.open(file_path, &:readline)

答案 1 :(得分:4)

我遇到了问题!我有同样的一个。调用read似乎可以执行您想要的操作(填充headers变量):

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

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

可能还有其他副作用我不知道,但这对我有用,并且闻起来不太糟糕。

答案 2 :(得分:2)

我不太明白这个问题。如果您使用其中一个迭代器方法,则可以很容易地对标题进行一些验证:

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