我有以下CSV数据:
10,11,12.34
我可以使用标准库中的CSV解析它,并将值从字符串转换为数字:
require 'csv'
CSV.parse( "10,11,12.34" )
=> [["10", "11", "12.34"]]
CSV.parse( "10,11,12.34", {:converters => [:integer,:integer,:float]} )
=> [[10, 11, 12.34]]
我不想要转换第1列,我只想将其作为字符串保留。我的猜测是我可以省略转换器数组中的值,但这不起作用:
CSV.parse( "10,11,12.34", {:converters => [nil,:integer,:float]} )
NoMethodError: undefined method `arity' for nil:NilClass
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:2188:in `convert_fields'
from org/jruby/RubyArray.java:1614:in `each'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:2187:in `convert_fields'
from org/jruby/RubyArray.java:2332:in `collect'
from org/jruby/RubyEnumerator.java:190:in `each'
from org/jruby/RubyEnumerator.java:404:in `with_index'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:2186:in `convert_fields'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:1923:in `shift'
from org/jruby/RubyKernel.java:1408:in `loop'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:1825:in `shift'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:1767:in `each'
from org/jruby/RubyEnumerable.java:391:in `to_a'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:1778:in `read'
from /home/ian/.rvm/rubies/jruby-1.6.6/lib/ruby/1.9/csv.rb:1365:in `parse'
from (irb):25:in `evaluate'
事实上,我还没有找到任何方法来指明我希望第一列不被转换。有什么建议吗?
更新
我认为我误解了:converters
的设计意图。它不是按列的1:1映射,而是要应用(我认为)所有值的转换器列表。我不确定,文档不太清楚。因此,更一般的问题是:如何在CSV中转换某些列,而不是其他列?
答案 0 :(得分:1)
documentation表示这些选项未按列指定,而是将应用于所有列的转换器列表。
示例:
CSV.parse("10,11,13,12.34", { :converters => [lambda{|s|s.to_s + 'x'}] })
# => [["10x", "11x", "13x", "12.34x"]]
由于CSV模块急于转换所有内容,您可以使用.to_s
移回所需的任何列,或使用:unconverted_fields
选项保存原始值并允许访问它们