2008-12-03 2 views
2

Я действительно борется с пониманием того, как эффективно использовать FasterCSV для выполнения того, что я хочу.RoR: FasterCSV to hash

У меня есть файл 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

Easy:

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

Hum, будет:

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

Пытаться разобрать CSV-файл, сделав `split (/, /)` путь к миру боли. Есть причина, почему драгоценный камень FasterCSV имеет более одной строки. – Eli 2008-12-03 23:37:29

+0

Хм, да, конечно, замените «File.open (« file.csv »). Readlines [1 ..- 1]» правильным способом чтения строк из FasterCSV и «line.split (/, /). Сначала «по правильному пути получения первого поля :-) – mat 2008-12-04 00:54:50

0

Я хотел бы использовать Еогеасп, и относиться к Nils с уважением - «неопределенный нолем + метод», иначе я бы рисковать ошибка ...

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