2008-12-03 30 views
2

我真的很努力地掌握如何有效地使用FasterCSV来完成我想要的。RoR:FasterCSV哈希

我有一个CSV文件;说:

ID,day,site 
test,tuesday,cnn.com 
bozo,friday,fark.com 
god,monday,xkcd.com 
test,saturday,whatever.com 

我该怎么通过这个文件,并结束了一个散列,有一个计数器第一列发生了多少次。所以:

["test" => 2, "bozo" => 1, "god" => 1] 

我需要能够做到这一点,而无需事先了解第一列中的值。

回答

5

简单:

h = Hash.new(0) 
FasterCSV.read("file.csv")[1..-1].each {|row| h[row[0]] += 1} 

工程与CSV.read相同,也是如此。

0

我没有在我面前的代码,但我相信row.to_hash这是否(其中row是当前记录的FasterCSV::Row

row.headers应该给你的头的数组,顺便说一句。检查文档的更多:http://fastercsv.rubyforge.org/classes/FasterCSV/Row.html

+0

但不会,仅仅把所有行哈希?这不是我想要的:我希望散列具有唯一出现的行[0]的计数器。任何其他想法? – neezer 2008-12-03 23:37:16

-2

哼哼,会:

File.open("file.csv").readlines[1..-1].inject({}) {|acc,line| word = line.split(/,/).first; acc[word] ||= 0; acc[word] += 1; acc} 

吗?

[1 ..- 1],因为我们不希望与列名

标题行做的话,每行,得到的第一个字,在蓄压器把0,如果它不存在,增加它,返回

+0

试图通过执行split(/,/)解析一个CSV文件是一个受到伤害的世界的路径。 FasterCSV宝石不止一行是有原因的。 – Eli 2008-12-03 23:37:29

+0

嗯,是的,当然,用正确的方式读取来自FasterCSV的行,替换“File.open(”file.csv“).readlines [1 ..- 1]”和“line.split(/ ).first“以正确的方式获取第一个字段:-) – mat 2008-12-04 00:54:50

0

我会使用的foreach,并尊重地对待尼尔斯 - “未定义无+法”,否则我就危险了错误...

counter = {} 
FasterCSV.foreach("path_to_your_csv_file", :headers => :first_row) do |row| 
    key=row[0] 
    counter[key] = counter[key].nil? ? 1 : counter[key] + 1 
end