2012-07-31 134 views
18

Ruby的CSV类使它很容易的每一行遍历:如何在Ruby中读取CSV时跳过标题行?

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

然而,这始终包括标题行,所以我会得到作为输出:

header1, header2 
foo, bar 
baz, yak 

我不虽然想要标题。现在,当我打电话......

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: :行对象而不是阵列

但是,怎么可以我跳过标题行,将行作为简单数组返回?我不想复杂的CSV::Row对象被返回。

我绝对不希望这样做:

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

检查http://stackoverflow.com/a/37856698/473040 – equivalent8 2016-06-16 10:35:29

回答

12

#shift从CSV类:用于包装的弦乐和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 
+0

CSV.read返回ans Array和#shift是数组的默认方法。并修正在这里非常有用。 – PriteshJ 2012-07-31 13:53:55

+0

你也可以迭代使用'each_with_index'并检查你正在使用哪一行索引。 'next if(i == 0)'会跳过索引'i'的第一行。 – tadman 2012-07-31 15:59:47

+0

@tadman随意张贴,作为一个单独的答案 - 看起来可行。 – slhck 2012-08-01 11:31:41

10

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

+1

注意:这只适用于Ruby 1.9 – inger 2013-05-15 16:42:16

+8

附加说明:如果您使用 ocodo 2013-12-16 23:33:14

6

一个很酷的方式忽略头被读取它作为一个数组,而忽略第一行:

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

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

相关问题