我还在努力解决基本问题,但我还没有找到在线答案。
我正在获取类似数据的CSV作为名称和数量:
Foo, 1.5
Bar, 1.2
Foo, 1.1
...
并希望将其合并为唯一名称,并将总计作为新值:
Foo, 2.6 #total of both Foo lines
Bar, 1.2
...
每次数据集都不大,但任务非常重复。
我尝试将其转换为哈希数组,找到uniq
名称,然后使用inject
,但不知怎的,它变得相当复杂并且无效。此外,循环所有内容似乎不是理想的方法。
有没有人有一个我错过的好的简单的想法或解决方案? (我只找到" Extract value from row in csv and sum it"用于PHP。)
答案 0 :(得分:3)
首先,您可以使用Ruby的CSV库来解析和转换您的CSV数据:
require 'csv'
csv_data = "Foo, 1.5\nBar, 1.2\nFoo, 1.1"
data_array = CSV.parse(csv_data, converters: :numeric)
#=> [["Foo", 1.5], ["Bar", 1.2], ["Foo", 1.1]]
要对值进行求和,我会使用散列和each_with_object
:
data_array.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v }
#=> {"Foo"=>2.6, "Bar"=>1.2}
答案 1 :(得分:1)
哈希数组似乎是最简单的方法:
让我们说:
CSV=[["foo",1.5],["bar",2.2],["foo",1.1]]
只是做:
myCSV=[["foo",1.5],["bar",1.2],["foo",1.1]]
myCSV.each_with_object(Hash.new(0.0)){|row,sum| sum[row[0]]+=row[1]}
=> {
"foo" => 2.6,
"bar" => 1.2
}
如果您正在阅读文件,使用CSV库或多或少相同:
sum=Hash.new(0.0)
CSV.foreach("path/to/file.csv") do |row|
sum[row[0]]+=row[1]
end
答案 2 :(得分:1)
为每个项目的第一次出现很好地传递0.0
作为哈希帐户的default选项:
input = [ ['Foo', 1.5],
['Bar', 1.2],
['Foo', 1.1] ]
result = input.inject(Hash.new(0.0)) do |sum, (key, value)|
sum[key] += value
sum
end
p result