ruby 如何将散列保存到 CSV 中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8183706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to save a hash into a CSV
提问by TheLegend
I am new in ruby so please forgive the noobishness.
我是 ruby 新手,所以请原谅 noobishness。
I have a CSV with two columns. One for animal name and one for animal type. I have a hash with all the keys being animal names and the values being animal type. I would like to write the hash to the CSV without using fasterCSV. I have thought of several ideas what would be easiest.. here is the basic layout.
我有一个包含两列的 CSV。一种用于动物名称,一种用于动物类型。我有一个哈希,所有键都是动物名称,值是动物类型。我想在不使用 fastCSV 的情况下将哈希写入 CSV。我已经想到了几个最简单的想法.. 这是基本布局。
require "csv"
def write_file
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "wb") do |csv|
csv << [???????????]
end
end
When I opened the file to read from it I opened it File.open("blabla.csv", headers: true)Would it be possible to write back to the file the same way?
当我打开文件以从中读取时,我打开了File.open("blabla.csv", headers: true)它是否可以以相同的方式写回文件?
回答by Joe Goggins
If you want column headers and you have multiple hashes:
如果您想要列标题并且您有多个散列:
require 'csv'
hashes = [{'a' => 'aaaa', 'b' => 'bbbb'}]
column_names = hashes.first.keys
s=CSV.generate do |csv|
csv << column_names
hashes.each do |x|
csv << x.values
end
end
File.write('the_file.csv', s)
(tested on Ruby 1.9.3-p429)
(在 Ruby 1.9.3-p429 上测试)
回答by S?awosz
Try this:
尝试这个:
require 'csv'
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "wb") {|csv| h.to_a.each {|elem| csv << elem} }
Will result:
将导致:
1.9.2-p290:~$ cat data.csv
dog,canine
cat,feline
donkey,asinine
回答by Tom Rossi
I think the simplest solution to your original question:
我认为对您的原始问题最简单的解决方案是:
def write_file
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "w", headers: h.keys) do |csv|
csv << h.values
end
end
With multiple hashes that all share the same keys:
使用多个共享相同密钥的哈希:
def write_file
hashes = [ { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' },
{ 'dog' => 'rover', 'cat' => 'kitty', 'donkey' => 'ass' } ]
CSV.open("data.csv", "w", headers: hashes.first.keys) do |csv|
hashes.each do |h|
csv << h.values
end
end
end
回答by rudolph9
CSV can take a hash in any order, exclude elements, and omit a params not in the HEADERS
CSV 可以采用任何顺序的散列,排除元素,并省略不在 HEADERS
require "csv"
HEADERS = [
'dog',
'cat',
'donkey'
]
def write_file
CSV.open("data.csv", "wb", :headers => HEADERS, :write_headers => true) do |csv|
csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
csv << { 'dog' => 'canine'}
csv << { 'cat' => 'feline', 'dog' => 'canine', 'donkey' => 'asinine' }
csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine', 'header not provided in the options to #open' => 'not included in output' }
end
end
write_file # =>
# dog,cat,donkey
# canine,feline,asinine
# canine,,
# canine,feline,asinine
# canine,feline,asinine
This makes working with the CSV class more flexible and readable.
这使得使用 CSV 类更加灵活和可读。
回答by peter
I tried the solutions here but got an incorrect result (values in wrong columns) since my source is a LDIF file that not always has all the values for a key. I ended up using the following.
我在这里尝试了解决方案,但得到了不正确的结果(错误列中的值),因为我的源是一个 LDIF 文件,它并不总是包含键的所有值。我最终使用了以下内容。
First, when building up the hash I remember the keys in a separate array which I extend with the keys that are not allready there.
首先,在构建散列时,我记住了单独数组中的键,我用尚未存在的键对其进行扩展。
# building up the array of hashes
File.read(ARGV[0]).each_line do |lijn|
case
when lijn[0..2] == "dn:" # new record
record = {}
when lijn.chomp == '' # end record
if record['telephonenumber'] # valid record ?
hashes << record
keys = keys.concat(record.keys).uniq
end
when ...
end
end
The important line here is keys = keys.concat(record.keys).uniqwhich extends the array of keys when new keys (headers) are found.
这里重要的一行是keys = keys.concat(record.keys).uniq在找到新键(标头)时扩展键数组。
Now the most important: converting our hashes to a CSV
现在最重要的是:将我们的哈希值转换为 CSV
CSV.open("export.csv", "w", {headers: keys, col_sep: ";"}) do |row|
row << keys # add the headers
hashes.each do |hash|
row << hash # the whole hash, not just the array of values
end
end
回答by Santosh Sharma
Try this:
尝试这个:
require 'csv'
data = { 'one' => '1', 'two' => '2', 'three' => '3' }
CSV.open("data.csv", "a+") do |csv|
csv << data.keys
csv << data.values
end
回答by shubham mishra
Lets we have a hash,
让我们有一个哈希,
hash_1 = {1=>{:rev=>400, :d_odr=>3}, 2=>{:rev=>4003, :d_price=>300}}
The above hash_1 having keys as some id 1,2,.. and values to those are again hash with some keys as (:rev, :d_odr, :d_price). Suppose we want a CSV file with headers,
上面的 hash_1 具有一些 id 1,2,.. 的键和那些值再次散列,一些键为 (:rev, :d_odr, :d_price)。假设我们想要一个带有标题的 CSV 文件,
headers = ['Designer_id','Revenue','Discount_price','Impression','Designer ODR']
Then make a new array for each value of hash_1 and insert it in CSV file,
然后为 hash_1 的每个值创建一个新数组并将其插入到 CSV 文件中,
CSV.open("design_performance_data_temp.csv", "w") do |csv|
csv << headers
csv_data = []
result.each do |design_data|
csv_data << design_data.first
csv_data << design_data.second[:rev] || 0
csv_data << design_data.second[:d_price] || 0
csv_data << design_data.second[:imp] || 0
csv_data << design_data.second[:d_odr] || 0
csv << csv_data
csv_data = []
end
end
Now you are having design_performance_data_temp.csv file saved in your corresponding directory. Above code can further be optimized.
现在您将 design_performance_data_temp.csv 文件保存在相应的目录中。以上代码可以进一步优化。

