鉴于我有以下代码,我需要做些什么才能使其正常工作?
config = {} #options for faster csv
input_file = "foo.csv"
# can be in any class or module
def count_item_groups(items)
results = Hash.new(0)
(items || []).each do |current|
results[current.to_s] += 1
end
results
end
row_value_iterator = FasterCSV.foreach(input_file, config) do |row|
yield return row[1]
end
result = count_item_groups(row_value_iterator)
这样的代码
def do_it_all
results = Hash.new(0)
FasterCSV.foreach(input_file, config) do |row|
results[row[1].to_s] += 1
end
results
end
结果应该是具有行[1]值的键的散列。 Ruby中不存在yield return
,但我确信Ruby可以处理这种类型的代码。
答案 0 :(得分:4)
这就是我理解你所问的问题:“我怎样才能将像FasterCSV.foreach
这样的方法转换为必要的(通过副作用)到功能性的东西(产生值),这样我就能模块化我的代码”。
答案:在Ruby中,您可以使用Object#enum_for将每个方法转换为 Enumerator 对象。现在,您可以将count_item_groups
与map
的输出结合使用,但我建议您使用Facets'Enumerable#frequency:
results = FasterCSV.enum_for(:foreach, "file.csv", {}).map do |row|
row[1].to_s
end.frequency
#=> {"val1"=>3, "val2"=>1}
答案 1 :(得分:0)
我不确定你在问什么,我认为这与可连接的功能有关。
不是将对象迭代器作为参数传递给另一个迭代器,而是在ruby中链接这些迭代器。它的迁移看起来像这样。
row_value_iterator = FasterCSV.foreach(input_file, config).map do |row|
row[1]
end
result = row_value_iterator.each_with_object(Hash.new(0)) do |current,results|
results[current.to_s] += 1
end
或者以真正的连锁风格做到:
result = FasterCSV.foreach(input_file,config).each_with_object(Hash.new(0)) do |row,results|
results[row[1].to_s] += 1
end