开发者

Ignore first line on csv parse Rails

开发者 https://www.devze.com 2022-12-29 20:57 出处:网络
I am using the code from this tutorial to parse a CSV file and add the contents to a database table. How would I ignore the first line of the 开发者_StackOverflow社区CSV file? The controller code is b

I am using the code from this tutorial to parse a CSV file and add the contents to a database table. How would I ignore the first line of the 开发者_StackOverflow社区CSV file? The controller code is below:

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


This question kept popping up when i was searching for how to skip the first line with the CSV / FasterCSV libraries, so here's the solution that if you end up here.

the solution is... CSV.foreach("path/to/file.csv",{:headers=>:first_row}) do |row|

HTH.


@parsed_file.each_with_index  do |row, i|
  next if i == 0
  ....


If you identify your first line as headers then you get back a Row object instead of a simple Array.

When you grab cell values, it seems like you need to use .fetch("Row Title") on the Row object.

This is what I came up with. I'm skipping nil with my if conditional.

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


Using this simple code, you can read a CSV file and ignore the first line which is the header or field names:

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

You can do what ever you want with row. Don't forget headers: true


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> 

here where it's the fun part

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">

So therefore I can do

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


data_rows_only = csv.drop(1)

will do it

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

will loop it

0

精彩评论

暂无评论...
验证码 换一张
取 消