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

标签 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 >

我不明白 value phone number 在哪里?我希望电话号码是 0311112222 而不是 52728978

最佳答案

发生这种情况的原因是,per the docs , CSV.table 是:

A shortcut for:

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

然后您可以通过将它作为 converters: 选项传递给 CSV.table 来使用它,这将覆盖默认的 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);我们必须手动调用这两个转换器。 (如果有人知道我遗漏了什么,请发表评论。)

关于ruby-on-rails - 如果它在 ruby​​ 中以零开头,我无法从 csv 文件中获取确切的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52025841/

相关文章:

php - 将 php 数组转换为 csv 字符串

php - 如何知道哪个变量有值,哪个为空?

javascript - rails 形式 : change form fields from previously selected fields

ruby-on-rails - Redmine 中的 Rake 任务出错

ruby-on-rails - 无法安装 gem debugger -v '1.6.5'

ruby - erb 定义最小值和最大值

ruby-on-rails - Phusion Passenger 不在 Apache 上工作

ruby-on-rails - 资源路径如何工作(内部)?我需要修复的不良行为

ruby - 如何在 ruby​​ 中对字母数字数组进行排序

ios - 在文本字段中自动添加连字符但无法编辑文本字段(电话号码屏蔽)