Bir CSV dosyasını Ruby ile bir diziye okumak yeterince kolaydır, ancak CSV dosyasına bir dizinin nasıl yazılacağına dair iyi bir belge bulamıyorum. Biri bana bunun nasıl yapılacağını söyleyebilir mi?
Bu önemliyse Ruby 1.9.2 kullanıyorum.
Bir CSV dosyasını Ruby ile bir diziye okumak yeterince kolaydır, ancak CSV dosyasına bir dizinin nasıl yazılacağına dair iyi bir belge bulamıyorum. Biri bana bunun nasıl yapılacağını söyleyebilir mi?
Bu önemliyse Ruby 1.9.2 kullanıyorum.
Yanıtlar:
Bir dosyaya:
require 'csv'
CSV.open("myfile.csv", "w") do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
Bir dizeye:
require 'csv'
csv_string = CSV.generate do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
CSV hakkındaki mevcut belgeler şunlardır: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html
Bunu sadece bir satıra indirdim.
rows = [['a1', 'a2', 'a3'],['b1', 'b2', 'b3', 'b4'], ['c1', 'c2', 'c3'], ... ]
csv_str = rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join("")
#=> "a1,a2,a3\nb1,b2,b3\nc1,c2,c3\n"
Yukarıdakilerin tümünü yapın ve bir satırda bir csv'ye kaydedin.
File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))}
NOT:
Aktif bir kayıt veritabanı csv dönüştürmek için bence böyle bir şey olurdu
CSV.open(fn, 'w') do |csv|
csv << Model.column_names
Model.where(query).each do |m|
csv << m.attributes.values
end
end
Hmm @tamouse, bu gist csv kaynağını okumadan benim için biraz kafa karıştırıcı, ancak genel olarak, dizinizdeki her karmanın aynı sayıda k / v çiftine sahip olduğunu ve anahtarların her zaman aynı, aynı sırada olduğunu varsayarak (yani eğer verileriniz yapılandırılmışsa) bu işlem aşağıdaki gibidir:
rowid = 0
CSV.open(fn, 'w') do |csv|
hsh_ary.each do |hsh|
rowid += 1
if rowid == 1
csv << hsh.keys# adding header row (column labels)
else
csv << hsh.values
end# of if/else inside hsh
end# of hsh's (rows)
end# of csv open
Verileriniz yapılandırılmamışsa, bu kesinlikle işe yaramaz
inject
Burada yanlış kullanıyorsunuz , gerçekten kullanmak istiyorsunuz map
. Ayrıca, join
varsayılan olarak boş bir dize iletmeniz gerekmez . Böylece bunu daha da daraltabilirsiniz:rows.map(&CSV.method(:generate_line).join
CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }
eşdeğer bir CSV oluşturur.
Eğer ilgilenen varsa, işte bazı tek satırlar (ve CSV'de tür bilgisi kaybına ilişkin bir not):
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
Not: CSV tüm tür bilgilerini kaybeder, temel tür bilgilerini korumak için JSON'u kullanabilir veya tüm tür bilgilerini korumak için ayrıntılı (ancak daha kolay insan tarafından düzenlenebilir) YAML'ye gidebilirsiniz - örneğin, tarih türüne ihtiyacınız varsa, CSV ve JSON dizeleri.
@ Boulder_ruby'nin cevabına dayanarak, bu benim özümden olduğu us_eco
gibi CSV tablosunu içerdiğini varsayarak arıyorum .
CSV.open('outfile.txt','wb', col_sep: "\t") do |csvfile|
csvfile << us_eco.first.keys
us_eco.each do |row|
csvfile << row.values
end
end
En özünü Güncelleme https://gist.github.com/tamouse/4647196
Bununla kendim mücadele ediyorum. Bu benim almam:
https://gist.github.com/2639448 :
require 'csv'
class CSV
def CSV.unparse array
CSV.generate do |csv|
array.each { |i| csv << i }
end
end
end
CSV.unparse [ %w(your array), %w(goes here) ]
[ %w(your array), %w(goes here) ]
güzel görünmeyecek. github.com/pry/pry/issues/568