2009-05-29 20 views
6

Sto scrivendo un'app che ruota attorno al set di dati numerici da un file. Tuttavia, dal momento che i dati vengono acquisiti in forma di stringa, devo convertirlo in float, che è dove inizia il divertimento. La sezione del mio codice è come mostrato (linee 65-73):Conversione di matrici di stringhe su matrici di galleggianti

ft = [] 
    puts "File Name: #{ARGV[0]}" 
    File.open(ARGV[0], "r") do |file| 
     file.each_line do |line| 
      ft << line.scan(/\d+/) 
     end 
    end 

ft.collect! {|i| i.to_f} 

questo funziona bene in irb, cioè, l'ultima riga cambia l'array di carri allegorici.

irb(main):001:0> ft = ["10", "23", "45"] 
=> ["10", "23", "45"] 
irb(main):002:0> ft.collect! {|i| i.to_f} 
=> [10.0, 23.0, 45.0] 

Tuttavia quando faccio funzionare la mia applicazione ottengo questo errore:

ruby-statistics.rb:73:in `block in <main>': undefined method `to_f' for #<Array: 
0x50832c> (NoMethodError) 
     from ruby-statistics.rb:73:in `collect!' 
     from ruby-statistics.rb:73:in `<main>' 

Qualsiasi aiuto con questo sarebbe apprezzato.

risposta

6

Si dovrebbe dare un'occhiata al formato di "ft" dopo aver letto il file.

Ogni linea viene memorizzato in un altro array quindi in realtà "ft" simile a questa:

[["1","2"],["3","4"]] 

Così si hanno a che fare qualcosa di simile:

ft = [] 
puts "File Name: #{ARGV[0]}" 
File.open(ARGV[0], "r") do |file| 
    file.each_line do |line| 
      ft << line.scan(/\d+/) 
    end 
end 

tmp = [] 

ft.each do |line| 
    line.each do |number| 
     tmp << number.to_f 
    end 
end 

puts tmp 

questa è solo una supposizione dal momento che non so come sia il tuo formato di file.

Edit:

Ecco come un one-liner:

ft.flatten!.collect! { |i| i.to_f } 
+0

Inoltre, non dimenticare che puoi utilizzare .inspect per esaminare ft: puts ft.inspect –

12

line.scan restituisce un array, quindi si sta inserendo un array in un array. La cosa più semplice da fare sarebbe chiamare flatten sull'array prima di convertire le stringhe in float.

ft = [] 
puts "File Name: #{ARGV[0]}" 
File.open(ARGV[0], "r") do |file| 
    file.each_line do |line| 
      ft << line.scan(/\d+/) 
    end 
end 

ft = ft.flatten.collect { |i| i.to_f }