#ruby-on-rails #ruby #csv #hash
#ruby-on-rails #ruby #csv #хэш
Вопрос:
Я хочу преобразовать хэш в csv в пользовательском формате в Ruby on Rails.
Входной хэш:
[{"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 00:00", "Price"=>"14"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 01:00", "Price"=>"13"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 02:00", "Price"=>"14"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 03:00", "Price"=>"19"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 04:00", "Price"=>"28"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 05:00", "Price"=>"24"}, {"Date"=>"2019-03-18", "Date Hour"=>"2019-03-18 06:00", "Price"=>"21"},
{"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 00:00", "Price"=>"16"}, {"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 01:00", "Price"=>"10"}, {"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 02:00", "Price"=>"11"}, {"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 03:00", "Price"=>"14"}, {"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 04:00", "Price"=>"26"}, {"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 05:00", "Price"=>"22"},
{"Date"=>"2019-03-19", "Date Hour"=>"2019-03-19 06:00", "Price"=>"25"}
Ожидаемый результат:
Date,Date Hour,Mar-18,Mar-19
2019-01-01,00:00,14,16
2019-01-01,01:00,13,10
2019-01-01,02:00,14,11
2019-01-01,03:00,19,14
2019-01-01,04:00,28,26
2019-01-01,05:00,24,22
2019-01-01,06:00,21,25
В настоящее время входной хэш имеет 2 даты, он может содержать несколько значений даты. На основе приведенных выше входных данных я хочу создать csv с ожидаемым результатом выше?
Как я могу получить вышеуказанный ожидаемый результат?
Обновление: Вот мой код. Но мой код работает только для данных за один день. Как я могу улучшить его, если данные хранятся во входном CSV в течение нескольких дней?
# Convert csv to hash
rows = CSV.parse(response, headers: true).map(amp;:to_h)
# Add transformation in hash
rows.each do |hash|
# Remove Hour from Date Hour values
hash["Date Hour"] = hash["Date Hour"].gsub!(hash["Date"], "").strip
# Replace Price column name with date value (e.g Mar-19)
hash[Date.parse(hash["Date"]).strftime("%b-%d")] = hash.delete("Price")
# Set static Date
hash["Date"] = "2019-01-01"
end
# Convert hash to csv
# Extract column names from first row of data
column_names = rows.first.keys
# Generate CSV after transformation of csv
csv_response = CSV.generate do |csv|
csv << column_names
rows.each do |row|
# Extract values for row of data
csv << row.values_at(*column_names)
end
end
Комментарии:
1. Пожалуйста, покажите, что вы уже пробовали. SO не является сервисом для написания кода для вас бесплатно.
2. Кроме того, неясно, почему ожидаемый результат имеет дату
Jan 1, 2019
, откуда берутся часы. Кроме того, ваш ввод является недопустимым ruby.3. @AlekseiMatiushkin Я обновил вопрос. Пожалуйста, взгляните. 1 января 2019 года является статическим значением даты.
Ответ №1:
Сначала преобразуйте входные данные:
result =
input.group_by do |hash|
hash["Date Hour"].split.last
end.values.map do |arr|
arr.each_with_object({}) do |h, acc|
acc["Date"] ||= "2019-01-01"
acc["Date Hour"] ||= h["Date Hour"].split.last
acc[Date.iso8601(h["Date"]).strftime('%b-%d')] = h["Price"]
end
end
#⇒ [{"Date"=>"2019-01-01", "Date Hour"=>"00:00", "Mar-18"=>"14", "Mar-19"=>"16"},
# {"Date"=>"2019-01-01", "Date Hour"=>"01:00", "Mar-18"=>"13", "Mar-19"=>"10"},
# {"Date"=>"2019-01-01", "Date Hour"=>"02:00", "Mar-18"=>"14", "Mar-19"=>"11"},
# {"Date"=>"2019-01-01", "Date Hour"=>"03:00", "Mar-18"=>"19", "Mar-19"=>"14"},
# {"Date"=>"2019-01-01", "Date Hour"=>"04:00", "Mar-18"=>"28", "Mar-19"=>"26"},
# {"Date"=>"2019-01-01", "Date Hour"=>"05:00", "Mar-18"=>"24", "Mar-19"=>"22"},
# {"Date"=>"2019-01-01", "Date Hour"=>"06:00", "Mar-18"=>"21", "Mar-19"=>"25"}]
Теперь просто передайте это в CSV.
Бесстыдный плагин: можно использовать SeeAsVee
gem для создания CSV-файла из массива хэшей:
require 'see_as_vee'
SeeAsVee.csv result
#⇒ #<File:/tmp/am/see_as_vee20190320-10403-ub0p5y.csv>
Комментарии:
1. Какая переменная имеет конечный результат? Я не вижу ожидаемого результата при печати входной переменной?
2. Результат был возвращен предложением, которое я опубликовал. Я ожидал, что вы сможете присвоить его переменной самостоятельно. Я обновил ответ.
3. Теперь я могу получить результат.