2010-05-12 15 views
9

Sto utilizzando il codice da this tutorial per analizzare un file CSV e aggiungere il contenuto a una tabella di database. Come ignorerei la prima riga del file CSV? Il codice di controllo è al di sotto:Ignora la prima riga su csv parse Rails

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 

risposta

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

Ordinare n confronti extra – baash05

41

Questa domanda continuava ad emergere quando ero alla ricerca di come saltare la prima linea con le librerie CSV/FasterCSV, ecco la soluzione che se si finisce Qui.

la soluzione è ... CSV.foreach("path/to/file.csv",{:headers=>:first_row}) do |row|

HTH.

+5

È anche possibile passare hash '{: headers => true}' come secondo parametro. Funziona anche –

3

Se si identifica la prima riga come intestazioni, si ottiene un oggetto anziché un semplice Array.

Quando si acquisiscono i valori delle celle, sembra che sia necessario utilizzare .fetch("Row Title") sull'oggetto .

Questo è quello che mi è venuto in mente. Sto saltando nil con il mio condizionale if.

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

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

qui, dove è la parte divertente

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

Così dunque posso fare

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 
0
data_rows_only = csv.drop(1) 

lo farà

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

volontà loop

0

Usando questo semplice codice, è possibile leggere un file CSV e ignorare la prima linea, che è l'intestazione o campo nomi:

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

Si può fare quello che volete con row. Non dimenticare headers: true

Problemi correlati