0

私は Ruby を初めて使用し、簡単な答えがあると思われる問題に取り組んできました。2 つの CSV ファイルがあり、1 つは 2 列で、もう 1 つは 1 列です。単一の列は、最初のファイルの 1 つの列に存在する値のサブセットです。例:

ファイル1.csv:

abc,123
def,456
ghi,789
jkl,012

file2.csv:

def
jkl

必要なのは、file2 の各値に対して file1 の列 2 の値を検索し、結果を別のファイルに出力することだけです。したがって、この場合、私の出力ファイルは次のもので構成される必要があります。

456
012

私はそれをこのように機能させました:

pairs=IO.readlines("file1.csv").map { |columns| columns.split(',') }

f1 =[]
pairs.each do |x| f1.push(x[0]) end

f2 = IO.readlines("file2.csv").map(&:chomp)

collection={}
pairs.each do |x| collection[x[0]]=x[1] end

f=File.open("outputfile.txt","w")
  f2.each do |col1,col2| f.puts collection[col1] end
f.close

...しかし、もっと良い方法が必要です。誰かがよりエレガントなソリューションを持っている場合、私は非常に感謝しています! (最終的には何百万行ものファイルでこれを実行する必要があるため、速度が問題になることにも注意してください。)

4

2 に答える 2

1

可能な限りメモリ効率を高めるために、完全な file2 (2 つの入力ファイルのうち小さい方のファイルを収集します) のみをメモリに読み込むことをお勧めします。高速検索と結果の値の格納にハッシュを使用しているため、file1 を読み通す際に、必要なキーの値のみを格納します。さらに一歩進んで、file2 の読み取り中に outputfile を書き込むことができます。

require 'CSV'

# Read file 2, the smaller file, and store keys in result Hash
result = {}
CSV.foreach("file2.csv") do |row|
  result[row[0]] = false
end

# Read file 1, the larger file, and look for keys in result Hash to set values
CSV.foreach("file1.csv") do |row|
  result[row[0]] = row[1] if result.key? row[0]
end

# Write the results
File.open("outputfile.txt", "w") do |f|
  result.each do |key, value|
    f.puts value if value
  end
end
于 2012-09-13T07:24:49.370 に答える
0

Ruby 1.9.3 でテスト済み

ファイル 1 の解析

data_csv_file1 = File.read("file1.csv")
data_csv1 = CSV.parse(data_csv_file1, :headers => true)

ファイル 2 の解析

data_csv_file2 = File.read("file2.csv")
data_csv2 = CSV.parse(data_csv_file1, :headers => true)

名前のコレクション

names_from_sheet1 = data_csv1.collect {|data| data[0]} #returns an array of names

names_from_sheet2 = data_csv2.collect {|data| data[0]} #returns an array of names

common_names = names_from_sheet1 & names_from_sheet2 #array with common names

印刷する結果を収集する

 results = [] #this will store the values to be printed
 data_csv1.each {|data| results << data[1] if common_names.include?(data[0]) }

最終出力

  f = File.open("outputfile.txt","w")
    results.each {|result| f.puts result }
    f.close
于 2012-09-13T06:41:48.400 に答える