【问题标题】:Ignore first line on csv parse Rails忽略 csv 解析 Rails 上的第一行
【发布时间】:2010-05-12 12:20:56
【问题描述】:

我正在使用来自this tutorial 的代码来解析 CSV 文件并将内容添加到数据库表中。我将如何忽略 CSV 文件的第一行?控制器代码如下:

def csv_import 
  @parsed_file=CSV::Reader.parse(params[:dump][:file])
  n = 0
  @parsed_file.each  do |row|
    s = Student.new
    s.name = row[0]
    s.cid = row[1]
    s.year_id = find_year_id_from_year_title(row[2])
    if s.save
      n = n+1
      GC.start if n%50==0
    end
    flash.now[:message] = "CSV Import Successful, #{n} new students added to the database."
  end
  redirect_to(students_url)
end

【问题讨论】:

    标签: ruby-on-rails csv


    【解决方案1】:

    当我在搜索如何使用 CSV / FasterCSV 库跳过第一行时,这个问题不断弹出,所以如果您最终来到这里,这就是解决方案 that

    解决方案是... CSV.foreach("path/to/file.csv",{:headers=>:first_row}) do |row|

    HTH。

    【讨论】:

    • 您也可以将哈希{:headers => true} 作为第二个参数传递。这也有效。
    【解决方案2】:
    @parsed_file.each_with_index  do |row, i|
      next if i == 0
      ....
    

    【讨论】:

    • 我对此投了反对票,因为这不是很好的自记录代码。将选项中的headers: true 传递给解析器的声明式风格更加清晰。
    【解决方案3】:

    如果您将第一行标识为标题,那么您将返回一个 Row 对象,而不是一个简单的 Array

    当您获取单元格值时,您似乎需要在 Row 对象上使用 .fetch("Row Title")

    这就是我想出的。我用我的if 条件跳过nil

    CSV.foreach("GitHubUsersToAdd.csv",{:headers=>:first_row}) do |row| username = row.fetch("GitHub Username") if username puts username.inspect end end

    【讨论】:

      【解决方案4】:

      使用这个简单的代码,您可以读取 CSV 文件并忽略作为标题或字段名称的第一行:

      CSV.foreach(File.join(File.dirname(__FILE__), filepath), headers: true) do |row|
          puts row.inspect
      end
      

      您可以使用row 为所欲为。别忘了headers: true

      【讨论】:

        【解决方案5】:
        require 'csv'
        csv_content =<<EOF
        lesson_id,user_id
        5,3
        69,95
        EOF
        
        parse_1 = CSV.parse csv_content
        parse_1.size # => 3  # it treats all lines as equal data
        
        parse_2 = CSV.parse csv_content, headers:true
        parse_2.size # => 2  # it ignores the first line as it's header
        
        parse_1
        # => [["lesson_id", "user_id"], ["5", "3"], ["69", "95"]]     
        parse_2
        # => #<CSV::Table mode:col_or_row row_count:3> 
        

        这里是有趣的部分

        parse_1.each do |line|
          puts line.inspect        # the object is array
        end
        # ["lesson_id", "user_id"]
        # ["5", " 3"]
        # ["69", " 95"]
        
        
        parse_2.each do |line|
          puts line.inspect        # the object is `CSV::Row` objects
        end
        # #<CSV::Row "lesson_id":"5" "user_id":" 3">
        # #<CSV::Row "lesson_id":"69" "user_id":" 95">
        

        所以我可以这样做

        parse_2.each do |line|
          puts "I'm processing Lesson #{line['lesson_id']} the User #{line['user_id']}"
        end
        # I'm processing Lesson 5 the User 3
        # I'm processing Lesson 69 the User 95
        

        【讨论】:

          【解决方案6】:
          data_rows_only = csv.drop(1)
          

          会做的

          csv.drop(1).each do |row|
            # ...
          end
          

          循环播放

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-27
            • 1970-01-01
            相关资源
            最近更新 更多