28

Ruby 的CSV类使得遍历每一行变得非常容易:

CSV.foreach(file) { |row| puts row }

但是,这总是包括标题行,所以我会得到输出:

header1, header2
foo, bar
baz, yak

我不想要标题。现在,当我打电话时……</p>

CSV.foreach(file, :headers => true)

我得到这个结果:

#<CSV::Row:0x10112e510
    @header_row = false,
    attr_reader :row = [
        [0] [
            [0] "header1",
            [1] "foo"
        ],
        [1] [
            [0] "header2",
            [1] "bar"
        ]
    ]
>

当然,因为文档说:

此设置导致 #shift 以 CSV::Row 对象而不是数组的形式返回行

但是,如何跳过标题行,将该行作为简单数组返回?我不希望CSV::Row返回复杂的对象。

我绝对不想这样做:

first = true
CSV.foreach(file) do |row|
  if first
    puts row
    first = false
  else
    # code for other rows
  end
end
4

3 回答 3

16

查看 CSV 类中的#shift

包装字符串和 IO 的主要读取方法,从数据源中提取单行,解析并作为字段数组返回(如果不使用标题行)

一个例子:

require 'csv'

# CSV FILE
# name, surname, location
# Mark, Needham, Sydney
# David, Smith, London

def parse_csv_file_for_names(path_to_csv)
  names = []  
  csv_contents = CSV.read(path_to_csv)
  csv_contents.shift
  csv_contents.each do |row|
    names << row[0]
  end
  return names
end
于 2012-07-31T12:57:04.220 回答
16

您可能需要考虑CSV.parse(csv_file, { :headers => false })并传递一个块,如此处所述

于 2012-07-31T21:08:21.640 回答
9

忽略标题的一种很酷的方法是将其作为数组读取并忽略第一行:

data = CSV.read("dataset.csv")[1 .. -1]
# => [["first_row", "with data"],
      ["second_row", "and more data"],
      ...
      ["last_row", "finally"]]

:headers => false方法的问题是CSV不会尝试将第一行作为标题读取,而是将其视为数据的一部分。所以,基本上,你有一个无用的第一行。

于 2013-12-16T23:30:50.217 回答