Подтвердить что ты не робот

Преобразование CSV файла в массив хэшей

У меня есть файл csv, некоторые статистики хоккея, например:

09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5

Я хочу сохранить их в массиве хэшей. У меня нет заголовков, и я хотел бы добавить ключи к каждому значению, например "time" => "09.09.2008" и так далее. Каждая строка должна быть доступна как arr[i], каждое значение, например, arr[i]["time"]. Я предпочитаю CSV класс, а не FasterCSV или split. Можете ли вы показать путь или перенаправить на какой-то поток, где была решена подобная проблема?

4b9b3361

Ответ 1

Вы можете использовать Ruby CSV parser для его синтаксического анализа, а затем использовать Hash[ keys.zip(values) ], чтобы сделать его хешем.

Пример:

test = '''
09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5
'''.strip

keys = ['time', etc... ]
CSV.parse(test).map {|a| Hash[ keys.zip(a) ] }

Ответ 2

Просто пройдите headers: true

CSV.foreach(data_file, headers: true) do |row|
  puts row.inspect # hash
end

Оттуда вы можете манипулировать хешем, как вам нравится.

(Протестировано с Ruby 2.0, но я думаю, что это работало довольно долго.)

Изменить

Вы говорите, что у вас нет заголовков. Не могли бы вы добавить строку заголовка в начало содержимого файла после прочтения?

Ответ 3

Это фантастическая статья Джоша Николса, в которой объясняется, как делать то, что вы просите.

Подводя итог, здесь его код:

csv = CSV.new(body, :headers => true, :header_converters => :symbol, :converters => [:all, :blank_to_nil])
csv.to_a.map {|row| row.to_hash }
=> [{:year=>1997, :make=>"Ford", :model=>"E350", :description=>"ac, abs, moon", :price=>3000.0}, {:year=>1999, :make=>"Chevy", :model=>"Venture \"Extended Edition\"", :description=>nil, :price=>4900.0}, {:year=>1999, :make=>"Chevy", :model=>"Venture \"Extended Edition, Very Large\"", :description=>nil, :price=>5000.0}, {:year=>1996, :make=>"Jeep", :model=>"Grand Cherokee", :description=>"MUST SELL!\nair, moon roof, loaded", :price=>4799.0}]

Итак, вы можете сохранить тело вашего CSV файла в строку с именем body.

body = "09.09.2008,1,HC Vitkovice Steel,BK Mlada Boleslav,1:0 (PP)
09.09.2008,1,HC Lasselsberger Plzen,RI OKNA ZLIN,6:2
09.09.2008,1,HC Litvinov,HC Sparta Praha,3:5"

И затем запустите его код, как указано выше.

Ответ 4

Незначительное изменение на Натан Лонг ответ

data_file = './sheet.csv'
data = []
CSV.foreach(data_file, headers: true) do |row|
  data << row.to_hash
end

Теперь data представляет собой массив хэшей, чтобы выполнить ваши ставки!

Ответ 5

Вы можете попробовать следующий камень и

require 'csv_hasher'
arr_of_hashes = CSVHasher.hashify('/path/to/csv/file')

Ключами возвращенных хэшей будут значения заголовка файла csv.

Если вы хотите передать свои собственные ключи, то

keys = [:key1, :key2, ... ]
arr_of_hashers = CSVHasher.hashify('/path/to/csv/file', { keys: keys })