【问题标题】:Ruby CSV not reading comma-formatted numbers in quoted stringsRuby CSV 不读取带引号的字符串中的逗号格式数字
【发布时间】:2015-02-03 19:01:06
【问题描述】:

我在 Rails 应用程序中使用 ruby​​ 的 CSV 类(ruby 2.1.5)从上传的 csv 文件加载记录。用户正在使用“另存为”从 Excel 创建 csv 文件,并且根据数字的格式,它们可能会保存为带逗号的带引号的字符串——在这种情况下,逗号后面的数字部分将被删除。

如果输入值为"3,500",则应保存3500,但改为3。

我意识到可以在 Excel 中清理它,但它似乎也应该很容易处理(如果我必须告诉他们程序无法处理这个问题,我会从用户那里得到一个主要的 WTF基本情况。)此外,由于 csv 文件的标题与数据库中的列名匹配,我不必编写特定于列的处理程序 - 我只需进行属性分配。我希望保持这种状态,因为我的受影响列比我在示例中包含的要多得多。

输入记录:

recordid,valcurrent,valdate
11015,"3,500",6/7/2013

处理函数

def import_csv(file)
  CSV.foreach(file.path, headers: true, header_converters: :symbol, skip_blanks: true, converters: :all) do |row|
    # hash the input row 
    row_hash = row.to_hash
    # create a new row with the hash in original_record
    fl = self.forecast_lines.create(original_record: row_hash.to_s)
    # write the hash to the record attributes
    fl.attributes = row_hash
    fl.save
  end
end

原始记录哈希:

Original record: {:recordid=>"11015", :valcurrent=>"3,500", :valdate=>"6/7/2013"} 

valcurrent 的数据类型是浮点数。但是保存到数据库中的有效值不是3500.0,而是3.0。

【问题讨论】:

    标签: ruby-on-rails ruby csv


    【解决方案1】:

    您可以添加一个自定义转换器来正确处理您的数字列。不确定这是否涵盖了所有可能的格式选项,但它看起来像这样:

    创建一个 lambda:

    comma_numbers = ->(s) {(s =~ /^\d+,/) ? (s.gsub(',','').to_f) : s}
    

    将其添加到您的转换器中:

    CSV::Converters[:comma_numbers] = comma_numbers
    

    新转换器不包含在转换器中::所有,所以将其添加为数组:

    converters: [:all, :comma_numbers]
    

    【讨论】:

    • 谢谢 - 这很好用,现在你已经让我指出了正确的方向,我将能够使用它来处理其他情况。
    • 我根据我为使其工作所做的工作对您的答案进行了编辑,但如果有更好的方法,请更正。
    • 谢谢。我更新了上面的答案,明确指出您必须将新转换器添加到您的转换器列表中。
    【解决方案2】:

    问题不在于 CSV,而在于 Ruby 如何将字符串转换为浮点数。

    在 Ruby 中:

    "3,500".to_f => 3.0
    

    这就是 3.0 被存储在数据库中的原因。你应该改变你的 import_csv 方法来处理逗号。

    另外,我认为您不应该在 create 中执行 row_hash.to_s。像这样的 Create 方法接受哈希作为参数。

    【讨论】:

    • 我得到了关于字符串到浮点数转换的第一点,但我认为使用转换器: :all 会导致 CSV 为我转换数字。关于你的第二点,我实际上想将整个哈希保存为一个名为 original_record 的字段中的字符串以用于调试目的 - 在我的 OP 中没有解释这一点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2016-01-18
    • 2014-12-18
    • 2020-05-11
    • 1970-01-01
    • 2020-06-09
    • 2016-06-08
    相关资源
    最近更新 更多