说明
在ruby中读取csv文件。
我有一个csv文件with this content
longitude,latitude,phone
13,139.7113134,35.56712836,0311112222
我读取了csv文件。
代码
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
答案 0 :(得分:2)
发生这种情况的原因是per the docs,CSV.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