2013-08-08 63 views
5

私がする必要があるのは、CSVファイルからヘッダーを取得することだけです。RubyのCSVファイルからヘッダーを取得する最も簡単な方法は何ですか?

file.csvになりは次のとおりです。

"A", "B", "C" 
"1", "2", "3" 

私のコードは次のとおりです。私に与え

table = CSV.open("file.csv", :headers => true) 

puts table.headers 

table.each do |row| 
    puts row 
end 

true 
"1", "2", "3" 

私は時間のためにRubyのCSVドキュメントを見てきたし、これは私を夢中にさせている。私はヘッダーを私に返すことができるシンプルな1ライナーがなければならないと確信しています。何か案は?上記

headers = CSV.read("file.csv", headers: true).headers 
# => ["A", "B", "C"] 

本当にCSV.open("file.csv", headers: true).read.headersのためだけのショートカットです:

答えて

11

それはあなたがheadersメソッドにアクセスできるようになりますCSV.readのように見えます。試してみたところ、CSV.openを使用していた可能性がありますが、メソッドを呼び出すときにCSV.openがファイルを実際に読み取っていないため、実際にデータが読み取られるまでヘッダーの内容を知る方法はありません。このため、例ではtrueが返されます。いくつかのデータを読んだ後、それは最終的に、ヘッダーを返します:

table = CSV.open("file.csv", :headers => true) 
    table.headers 
    # => true 
    table.read 
    # => #<CSV::Table mode:col_or_row row_count:2> 
    table.headers 
    # => ["A", "B", "C"] 
0

あなたは短い答えは、次に試すことができますしたい場合は:私の意見では

headers = CSV.open("file.csv", &:readline) 
# => ["A", "B", "C"] 
+0

知っているが、私は@ディラン-Markowが示唆するより明示的な '.headers'アプローチを選ぶと思います。また、以下の

は私がCSV.foreachCSV.readをベンチマーキングするために使用されるスクリプトです。 –

3

これを行うための最善の方法は次のとおりです。

したがって、メモリとで

headers = CSV.foreach('file.csv').first

その非常に魅力的CSV.read('file.csv'. headers: true).headersを使用することに注意してくださいしかし、漁獲量があり、CSV.read負荷完全なファイルを株式会社あなたのメモリフットプリントを元に戻し、大きなファイルに使用するのが非常に遅くなります。可能であれば、CSV.foreachをご利用ください。

Ruby version: ruby 2.4.1p111 
File size: 20M 
**************** 
Time and memory usage with CSV.foreach: 
Time: 0.0 seconds 
Memory: 0.04 MB 
**************** 
Time and memory usage with CSV.read: 
Time: 5.88 seconds 
Memory: 314.25 MB 

20メガバイトのファイルがどのような1GBのファイルを想像CSV.readで314メガバイトでメモリフットプリントを増やす:以下 はわずか20 MBのファイルのためのベンチマークです。一言で言えば、CSV.readを使用しないでください。システムが300MBのファイルにダウンしました。

さらに読む: これについてさらに詳しく知りたい場合は、hereは大きなファイルの処理に関する非常に良い記事です。

グッド
require 'benchmark' 
require 'csv' 
def print_memory_usage 
    memory_before = `ps -o rss= -p #{Process.pid}`.to_i 
    yield 
    memory_after = `ps -o rss= -p #{Process.pid}`.to_i 
    puts "Memory: #{((memory_after - memory_before)/1024.0).round(2)} MB" 
end 

def print_time_spent 
    time = Benchmark.realtime do 
    yield 
    end 
    puts "Time: #{time.round(2)} seconds" 
end 

file_path = '{path_to_csv_file}' 
puts 'Ruby version: ' + `ruby -v` 
puts 'File size:' + `du -h #{file_path}` 
puts 'Time and memory usage with CSV.foreach: ' 
print_memory_usage do 
    print_time_spent do 
    headers = CSV.foreach(file_path, headers: false).first 
    end 
end 
puts 'Time and memory usage with CSV.read:' 
print_memory_usage do 
    print_time_spent do 
    headers = CSV.read(file_path, headers: true).headers 
    end 
end 
関連する問題