Преобразование 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
. Можете ли вы показать путь или перенаправить на какой-то поток, где была решена подобная проблема?
Ответы
Ответ 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 })