我是Ruby的新手,我一直在努力解决一个我怀疑有一个简单答案的问题。我有两个CSV文件,一个有两列,一个有一列。单列是我的第一个文件的一列中存在的值的子集。例如:
file1.csv:
abc,123
def,456
ghi,789
jkl,012
file2.csv:
def
jkl
我需要做的就是在file1中为file2中的每个值查找第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
......但必须有更好的方法。如果有人有更优雅的解决方案,我会非常感激! (我还应该注意,我最终需要在包含数百万行的文件上运行它,因此速度将是一个问题。)
答案 0 :(得分:1)
为了尽可能保持内存效率,我建议只将完整的文件2(我收集的是两个输入文件中较小的一个)读入内存。我正在使用哈希来快速查找并存储结果值,因此当您通过file1读取时,您只存储所需键的值。您可以更进一步,在读取file2时编写输出文件。
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
答案 1 :(得分: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