我有 .csv 文件,其中每行代表一个具有特定持续时间、数量等的调用。我需要创建 Call 对象数组 - 每个 Call.new 都需要参数的哈希值,所以这很容易 - 只需要行来自 CSV。但由于某种原因它不起作用 - 当我调用 Call.new(raw_call) 时它是 nil 。
我也不可能看到任何输出 - 我将 puts
放置在代码中的各个位置( block 内等),但它根本不显示任何内容。我显然有另一个类 - Call
,它保存 Call 等的初始化。
require 'csv'
class CSVCallParser
attr_accessor :io
def initialize(io)
self.io = io
end
NAMES = {
a: :date,
b: :service,
c: :phone_number,
d: :duration,
e: :unit,
f: :cost
}
def run
parse do |raw_call|
parse_call(raw_call)
end
end
private
def parse_call(raw_call)
NAMES.each_with_object({}) do |name, title, memo|
memo[name] = raw_call[title.to_s]
end
end
def parse(&block)
CSV.parse(io, headers: true, header_converters: :symbol, &block)
end
end
CSVCallParser.new(ARGV[0]).run
我的 .csv 文件的小样本:标题和一行:
"a","b","c","d","e","f"
"01.09.2016 08:49","International","48627843111","0:29","","0,00"
最佳答案
我注意到一些事情没有按预期进行。在 parse_call
方法中,
def parse_call(raw_call)
NAMES.each_with_object({}) do |name, title, memo|
memo[name] = raw_call[title.to_s]
end
end
我尝试打印name
、title
和memo
。我期望得到 :a
、:date
和 {}
,但实际得到的是 [:a,:date ]
、{}
和 nil
。
此外,raw_call
header 是 :a,:b,:c...
,而不是 :date, :service...
,因此您应该使用 raw_call[name]
,并将其转换为字符串不会有帮助,因为键是 raw_call
中的符号。
所以我将函数修改为
def parse_call(raw_call)
NAMES.each_with_object({}) do |name_title, memo|
memo[name_title[1]] = raw_call[name_title[0]]
end
end
name_title[1]
返回标题(:date
、:service
等)
name_title[0]
返回名称(:a
、:b
等)
另外,在这个方法中
def run
parse do |raw_call|
parse_call(raw_call)
end
end
您没有返回得到的任何结果,因此您得到的是nil
,
所以我把它改成了
def run
res = []
parse do |raw_call|
res << parse_call(raw_call)
end
res
end
现在,如果我输出该行
p CSVCallParser.new(File.read("file1.csv")).run
我明白了(我在 csv 示例中又添加了两行)
[{:date=>"01.09.2016 08:49", :service=>"International", :phone_number=>"48627843111", :duration=>"0:29", :unit=>"", :cost=>"0,00"},
{:date=>"02.09.2016 08:49", :service=>"International", :phone_number=>"48622454111", :duration=>"1:29", :unit=>"", :cost=>"0,00"},
{:date=>"03.09.2016 08:49", :service=>"Domestic", :phone_number=>"48627843111", :duration=>"0:29", :unit=>"", :cost=>"0,00"}]
如果你想像这样从终端运行这个程序
ruby csv_call_parser.rb calls.csv
(在本例中,calls.csv
作为参数传递给 ARGV
)
您可以通过修改 ruby 文件的最后一行来实现此目的。
p CSVCallParser.new(File.read(ARGV[0])).run
这也将像以前一样返回带有哈希值的数组。
关于Ruby - 读取 .csv 并从中创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39874886/