Достаточно просто прочитать CSV-файл в массив с помощью Ruby, но я не могу найти хорошую документацию о том, как записать массив в CSV-файл. Может кто-нибудь сказать мне, как это сделать?
У вас отличный ответ, но позвольте мне убедить вас не использовать CSV. Если у вас нет вкладок в ваших данных, с файлами, разделенными табуляцией, будет гораздо легче иметь дело, потому что они не включают в себя слишком много гребаных цитат, экранирования и тому подобного. Если вы должны использовать CSV, конечно, это перерывы.
Билл Дьюбер
8
@Bill, CSV-модуль аккуратно обрабатывает файлы с разделителями табуляции, а также фактические CSV-файлы. Опция: col_sep позволяет указать разделитель столбцов как "\ t", и все хорошо.
@ Давид, это файловый режим. «w» означает запись в файл. Если вы не укажете это, по умолчанию будет использоваться «rb» (бинарный режим только для чтения), и вы получите сообщение об ошибке при попытке добавить его в CSV-файл. См. Ruby-doc.org/core-1.9.3/IO.html для получения списка допустимых режимов файлов в Ruby.
Дилан Марков
15
Попался. А для будущих пользователей, если вы хотите, чтобы каждая итерация не перезаписывала предыдущий файл CSV, используйте опцию «ab».
Хм @tamouse, эта суть несколько смущает меня, не читая исходный код csv, но, в общем, предполагается, что каждый хэш в вашем массиве имеет одинаковое количество пар k / v и что ключи всегда одинаковы, в одном и том же порядке (т.е. если ваши данные структурированы), это должно сделать дело:
rowid =0
CSV.open(fn,'w')do|csv|
hsh_ary.each do|hsh|
rowid +=1if rowid ==1
csv << hsh.keys# adding header row (column labels)else
csv << hsh.values
end# of if/else inside hshend# of hsh's (rows)end# of csv open
Если ваши данные не структурированы, это явно не сработает
Я вытащил файл CSV с помощью CSV.table, сделал некоторые манипуляции, избавился от некоторых столбцов, и теперь я хочу снова превратить получившийся массив хэшей в CSV (действительно с разделителями табуляции). Как? gist.github.com/4647196
тамуза
хм ... эта суть несколько непрозрачна, но с учетом массива хэшей, все с одинаковым количеством пар к / в и одинаковыми ключами, в том же порядке ...
boulder_ruby
Спасибо, @boulder_ruby. Это будет работать. Данные представляют собой таблицу переписи, и суть этого довольно непрозрачна. :) Это в основном извлечение определенных столбцов из исходной таблицы переписи в подмножество.
tamouse
3
Вы неправильно используете injectздесь, вы действительно хотите использовать map. Кроме того, вам не нужно передавать пустую строку join, так как это по умолчанию. Таким образом, вы могли бы сократить это еще дальше к этому:rows.map(&CSV.method(:generate_line).join
iGEL
1
Ваш второй пример слишком сложен, поскольку библиотека CSV довольно мощная. CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }генерирует эквивалент CSV.
Если кому-то интересно, вот несколько однострочников (и примечание о потере информации о типах в CSV):
require 'csv'
rows =[[1,2,3],[4,5]]# [[1, 2, 3], [4, 5]]# To CSV string
csv = rows.map(&:to_csv).join # "1,2,3\n4,5\n"# ... and back, as String[][]
rows2 = csv.split("\n").map(&:parse_csv)# [["1", "2", "3"], ["4", "5"]]# File I/O:
filename ='/tmp/vsc.csv'# Save to file -- answer to your question
IO.write(filename, rows.map(&:to_csv).join)# Read from file# rows3 = IO.read(filename).split("\n").map(&:parse_csv)
rows3 = CSV.read(filename)
rows3 == rows2 # true
rows3 == rows # false
Примечание: CSV теряет всю информацию о типах, вы можете использовать JSON для сохранения базовой информации о типах или перейти к многословному (но более легко редактируемому) YAML для сохранения всей информации о типах - например, если вам нужен тип даты, который станет строки в CSV и JSON.
Ответы:
К файлу:
К строке:
Вот текущая документация по CSV: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html
источник
У меня это до одной строчки.
Выполните все вышеперечисленное и сохраните в формате csv в одну строку.
НОТА:
Я думаю, что конвертировать базу данных активных записей в CSV было бы что-то вроде этого
Хм @tamouse, эта суть несколько смущает меня, не читая исходный код csv, но, в общем, предполагается, что каждый хэш в вашем массиве имеет одинаковое количество пар k / v и что ключи всегда одинаковы, в одном и том же порядке (т.е. если ваши данные структурированы), это должно сделать дело:
Если ваши данные не структурированы, это явно не сработает
источник
inject
здесь, вы действительно хотите использоватьmap
. Кроме того, вам не нужно передавать пустую строкуjoin
, так как это по умолчанию. Таким образом, вы могли бы сократить это еще дальше к этому:rows.map(&CSV.method(:generate_line).join
CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }
генерирует эквивалент CSV.Если у вас есть массив массивов данных:
Затем вы можете записать это в файл со следующим, что, я думаю, намного проще:
источник
Если кому-то интересно, вот несколько однострочников (и примечание о потере информации о типах в CSV):
Примечание: CSV теряет всю информацию о типах, вы можете использовать JSON для сохранения базовой информации о типах или перейти к многословному (но более легко редактируемому) YAML для сохранения всей информации о типах - например, если вам нужен тип даты, который станет строки в CSV и JSON.
источник
Основываясь на ответе @ boulder_ruby, это то, что я ищу, предполагая, что
us_eco
содержит таблицу CSV, как из моей сути.Обновлен гист по адресу https://gist.github.com/tamouse/4647196
источник
Борюсь с этим сам. Это мое мнение:
https://gist.github.com/2639448 :
источник
[ %w(your array), %w(goes here) ]
не будет выглядеть красиво. github.com/pry/pry/issues/568