在Ruby中从带有标头的CSV加载数据

时间:2018-08-01 12:34:24

标签: ruby

我想加载CSV文件并基于数据创建对象。该文件具有以下结构:

product code;product name;product price;units
RTF0145;Mixer;659;15
GTF4895;PC;9999;25

在加载数据时,我想跳过带有标题的第一行,但是我在使用{:headers => true}属性时遇到了麻烦,该方法不执行任何操作,不会引发任何错误。

def Store.load_data(file, separator, headers = true)
  begin
    @items = []
    CSV.open(file, "r", {:col_sep => separator}, {:headers => headers}) do |csv|
      csv.each do |product|
        @items << Store.new(product["product code"], product["product name"], product["price"], product["units"])
      end
    end
  rescue
  end
end

我这样调用方法:

Store.load_data("products.csv", ";")

如果我不使用headers参数使用它,那么一切都会按预期进行:

  def Store.load_data(file, separator, headers = true)
    begin
      @items = []
      CSV.foreach(file, { :col_sep => separator }) do |row|
        @items << Store.new(row[0], row[1], row[2], row[3]) unless row[0] == "product code"
      end
    rescue
    end
  end

1 个答案:

答案 0 :(得分:0)

CSV.open方法的签名是:

CSV.open(filename, mode = "rb", options = Hash.new)

因此这样称呼它:

CSV.open(file, "r", { ... }, { ... }) 

...是不正确的,而Ruby应该会引发异常。

使用哈希调用CSV.open的正确方法是:

CSV.open(file, "r", { :a => b, :c => d, :e => f })

或者:

CSV.open(file, "r", :a => b, :c => d, :e => f)

因此,要解决您的问题,解决方案应该是对此进行更改:

CSV.open(file, "r", { :col_sep => separator }, { :headers => headers })

对此:

CSV.open(file, "r", { :col_sep => separator, :headers => headers })