Ruby 1.9 CSV:有选择地忽略列的转换

时间:2012-02-22 16:25:34

标签: ruby

我有以下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中转换某些列,而不是其他列?

1 个答案:

答案 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选项保存原始值并允许访问它们