2009-05-29 2 views
6

Я пишу приложение, которое вращается вокруг получения наборов числовых данных из файла. Однако, поскольку данные получены в строковой форме, я должен преобразовать их в float, где начинается забава. Соответствующий раздел моего кода, как показано (строки 65-73):Преобразование массива строк в массив поплавков

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} 

Это прекрасно работает в IRB, то есть, последняя строка изменяет массив поплавки.

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] 

Однако, когда я запускаю мое приложение, я получаю эту ошибку:

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

Любая помощь с этим была бы оценена.

ответ

6

Вы должны посмотреть на формат «ft» после прочтения файла.

Каждая строка сохраняется в другом массиве, так ведь «фут» выглядит примерно так:

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

Так что вы должны сделать что-то вроде этого:

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 

Это просто предположение так как я не знаю, как выглядит ваш формат файла.

Edit:

Вот как однострочника:

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

также не забывайте, что вы можете использовать. Inspect для изучения ft: puts ft.inspect –

12

line.scan возвращает массив, так что вы вставляете массив в массив. Проще всего было бы позвонить flatten в массив, прежде чем преобразовать строки в плавающие.

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 } 
Смежные вопросы