在 Ruby 中读取 CSV 时如何跳过标题行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11740439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:20:11  来源:igfitidea点击:

How can I skip the header row when reading a CSV in Ruby?

rubycsv

提问by slhck

Ruby's CSVclass makes it pretty easy to iterate over each row:

Ruby 的CSV类使迭代每一行变得非常容易:

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

However, this always includes the header row, so I'll get as output:

但是,这始终包括标题行,因此我将获得输出:

header1, header2
foo, bar
baz, yak

I don't want the headers though. Now, when I call …

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

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

I get this result:

我得到这个结果:

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

Of course, because the documentation says:

当然,因为文档说:

This setting causes #shift to return rows as CSV::Row objects instead of Arrays

此设置导致 #shift 将行作为 CSV::Row 对象而不是数组返回

But, how can I skip the header row, returning the row as a simple array?I don't want the complicated CSV::Rowobject to be returned.

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

I definitely don't want to do this:

我绝对不想这样做:

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

回答by waldyr.ar

Look at #shiftfrom CSV Class:

从 CSV 类中查看#shift

The primary read method for wrapped Strings and IOs, a single row is pulled from the data source, parsed and returned as an Array of fields (if header rows are not used)

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

An Example:

一个例子:

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

回答by jodell

You might want to consider CSV.parse(csv_file, { :headers => false })and passing a block, as mentioned here

你可能要考虑CSV.parse(csv_file, { :headers => false }),并传递一个块,提到这里

回答by agarie

A cool way to ignore the headers is to read it as an array and ignore the first row:

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

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

The problem with the :headers => falseapproach is that CSVwon't try to read the first row as a header, but will consider it part of the data. So, basically, you have a useless first row.

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