2012-02-23 16 views
3

商品#、商品、価格を記載した製品ファイルがあります。私はこのファイルを読んで、アイテム#がキーであり、製品と価格が値であるハッシュとして初期化したいと思います。ここに私のファイルですCSVのようなファイルからハッシュを作成する

199, Shoes, 59.99 
211, Shirts, 19.99 
245, Hats, 25.99 
689, Coats, 99.99 
712, Beanies, 6.99 

私はこのようにしたいと思います。

products = { 
    199 =>['Shoes', 59.99], 
    211 =>['Shirts', 19.99], 
    245 =>['Hats', 25.99], 
    689 => ['Coats', 99.99], 
    712 => ['Beanies', 6.99] 
} 

これは私が思いつくことができるもので、実際にはそれが望むものではありません。

products_file = File.open("files.txt") 
products_hash = [] 
while ! products_file.eof? 
    product_hash = products_file.gets.chomp 
    print product_hash.split(', ') 
end 

そして、ここで私が思い付いた出力です:CSVファイルには、products.csvと呼ばれ、これをしたとして、私はあなたのデータを保存した

["199", "Shoes", "59.99"] 
["211", "Shirts", "19.99"] 
["245", "Hats", "25.99"] 
["689", "Coats", "99.99"] 
["712", "Beanies", "6.99"] 

答えて

11

require 'csv' 
products = {} 
CSV.foreach("products.csv") do |line| 
    products[line[0].to_i] = [line[1].strip, line[2].to_f] 
end 
products 
#=> {199=>["Shoes", 59.99], 211=>["Shirts", 19.99], 245=>["Hats", 25.99], 689=>["Coats", 99.99], 712=>["Beanies", 6.99]} 

同じ結果をすることができますeach_with_objectを使用してより簡潔な方法で実現できますが、ファイル全体を一度に読み取るので、ファイルが大きい場合はお勧めできません。

require 'csv' 
products = CSV.read("products.csv").each_with_object({}) do |line, h| 
    h[line[0].to_i] = [line[1].strip, line[2].to_f] 
end 

もともとPhrogzにより示唆されるように、より機能的なアプローチは、もあります:

require 'csv' 
products = Hash[ CSV.read('products.csv').map do |row| 
    [ row[0].to_i, [row[1].strip,row[2].to_f] ] 
end ] 
+0

+1、偉大な答え。私はこのトピックに関する壊れた記録ですが、[私は 'each_with_object'(http://phrogz.net/tap-vs-each_with_object)で'タップ 'を主張します。 – Phrogz

+0

私の「タップ」の問題は、私が変換したいデータのメソッドを呼び出すのが好きであり、私の結果になる空のコレクションではありません。しかし、私はこの使用事例で 'into'、または' fill_with'が私の懸念を少し緩和する良いエイリアスになると思います。個人的に私は常に 'inject'を使いますが、新しいRubyistsは' each_with_object'を理解しやすいと分かりました。 –

1

変動は、CSVのコンバーターを使用してデータを操作する:

require 'csv' 
products = {} 
CSV.foreach('products.csv', {col_sep: ', ', converters: :numeric}) do |row| 
    products[row.shift] = row 
end 
p products 
#=> {199=>["Shoes", 59.99], 211=>["Shirts", 19.99], 245=>["Hats", 25.99], 689=>["Coats", 99.99], 712=>["Beanies", 6.99]} 
+0

+1、素敵な解決策。私の本来の目的は、コードをシンプルにしていくつかのRubyを披露することでしたが、私はあなたも両方をやっていると思います。 –

関連する問題