如果它在ruby中以零开头,我无法从csv文件中获取确切的数字

时间:2018-08-26 11:36:33

标签: ruby-on-rails ruby phone-number opencsv

说明

在ruby中读取csv文件。

  1. 我有一个csv文件with this content

    longitude,latitude,phone
    13,139.7113134,35.56712836,0311112222
    
  2. 我读取了csv文件。

  3. 我在列电话号码上没有得到数据

代码

uploaded_io = params[:rooms][:file]
rooms_table = CSV.table(uploaded_io.tempfile, encoding: "UTF-8")
rooms_table.each_with_index do |row, i|
  p row
end

puts row:

#<CSV::Row longitude:139.7113134 latitude:35.56712836 phone:52728978 >

我不知道电话号码在哪里?我希望电话号码是 0311112222代替52728978

2 个答案:

答案 0 :(得分:2)

发生这种情况的原因是per the docsCSV.table是:

  

快捷方式:

CSV.read( path, { headers:           true,
                  converters:        :numeric,
                  header_converters: :symbol }.merge(options) )

请注意converters: :numeric,它告诉它自动(尝试)将数字形式的字段转换为数字。当然,电话号码不是真正的数字,而是一串数字。

如果您不想进行任何会话,可以将converters: nil作为选项传递给CSV.table

假设您想让:numeric转换器仍在其他字段上运行,但是,您需要定义自己的转换器。转换器是一个Proc,它带有两个参数:字段值和(可选)FieldInfo对象。您的转换器可能看起来像这样:

NUMERIC_EXCEPT_PHONE_CONVERTER = lambda do |value, field_info|
  if field_info.header == :phone
    value
  else
    CSV::Converters[:float].call(
      CSV::Converters[:integer].call(value))
  end
end

然后,您可以通过将其作为CSV.table选项传递到converters:来使用它,它将覆盖默认的converters: :numeric

rooms_table = CSV.table("data.csv", encoding: "UTF-8", converters: NUMERIC_EXCEPT_PHONE_CONVERTER)
p rooms_table[0]
# => #<CSV::Row longitude:139.7113134 latitude:35.56712836 phone:"0311112222">

如您所见,phone的值现在是一个以0前导的字符串。

您可以在repl.it上看到以下代码:https://repl.it/@jrunning/WellmadeFarflungCron

在旁边

您为什么会问,这有点丑吗?

CSV::Converters[:float].call(
  CSV::Converters[:integer].call(value))

这是因为CSV模块因此定义了CSV :: Converters:

Converters  = {
  integer:   lambda { |f|
    Integer(f.encode(ConverterEncoding)) rescue f
  },
  float:     lambda { |f|
    Float(f.encode(ConverterEncoding)) rescue f
  },
  numeric:   [:integer, :float],
  # ...
}

由于:numeric转换器未指定为lambda,而是一个数组,指示它实际上只是:integer:float转换器的“链”,因此我们可以只是做CSV::Converters[:numeric].call(value);我们必须手动调用两个转换器。 (如果有人知道我想念的东西,请发表评论。)

答案 1 :(得分:1)

您可以更改:

rooms_table = CSV.table(uploaded_io.tempfile, encoding: "UTF-8")

收件人:

rooms_table = CSV.table(uploaded_io.tempfile, encoding: "UTF-8", converters: nil)

不会转换/转换您的字段(您将获得字符串)。默认转换器是:numeric,它执行您不需要的转换。

可以使用的可能的转换器在这里找到:

https://ruby-doc.org/stdlib-2.5.1/libdoc/csv/rdoc/CSV.html#Converters