2011-06-22 49 views
1

同一时间,我想读两个文本文件,并在同一时间处理它们,就像如下两个文件:过程在红宝石

f1 = File.open(...) 
f2 = File.open(...) 

|f1, f2|.each do |l1,l2| 
    ...... 
end 

我怎样才能做到这一点的红宝石?

+0

你的意思是你想要一步一步地从每个文件中同时获得同等的*行*吗?或者是其他东西? – Gareth

+0

你的问题有些欠定:文件的行数是否相同?如果不是,应该发生什么? – Telemachus

+1

为什么会有人投票结束这个问题?这不是世界上最激动人心的革命性问题,但这是一个完全合法的问题(虽然有点不清楚 - 请参阅我以前的评论)。 – Telemachus

回答

9

如何避免记忆吸马特的答案相关:

f1 = File.open(...) 
f2 = File.open(...) 

f1.each.zip(f2.each).each do |line1, line2| 
    # Do something with the lines 
end 

zip是在可枚举的许多不太知名的方法是非常值得了解一个人,特别是如果你有兴趣学习功能编程范例。

它避免了与matt的答案相关的内存吸收,因为它不是读取所有内容,而是返回一个枚举器,您只能在需要时使用它。

+2

+1在一个紧凑表达式中用于'each'的三种用法。值得一提的一个问题是:如果其中一个或另一个文件提前(尽管可以这么说 - 如果它更短),那么生成的压缩子数组将会充满'零',必须以某种方式测试或处理。这个问题出现,但是你处理这个问题,但我认为这是值得说。 – Telemachus

+1

@Telemachus:更糟糕的是,如果第一个文件提前排队,那么它会结束而不让你知道另一个文件仍然有行。 –

+0

+1使用'Enumerable#zip' – hdgarrood

0

这是对你有用的东西吗? :

File.readlines(file1).each do |line_of_file1| 
    File.readlines(file2).each do |line_of_file2| 
    # Do stuff with the lines 
    end 
end 
+3

如果file1中有n行,file2中有m行,则会有n * m个循环。 –

0
lines1 = File.open(...).readlines 
lines2 = File.open(...).readlines 

lines1.zip(lines2).each do |line1, line2| 
    ... 
end 
+1

根据文件的大小,“readlines”可能会成为内存吸引。不要说这不合适,但要记住。 – Telemachus

1
f1 = File.open(...) 
f2 = File.open(...) 

f1.each do |l1| 
    l2 = f2.gets.chomp 
    ...... 
end 
1

天真的方法,假设文件是​​相同的行数。这是完全手动的,但这个想法应该给你的东西的基础上:

f1 = File.open('foo.txt', 'r') 
f2 = File.open('bar.txt', 'r') 

while line1 = f1.gets && line2 = f2.gets 
    print "File 1: #{line1}" 
    print "File 2: #{line2}" 
end 

这只要任一两个文件的跑出线的停止(如果有一个比另一个更短)。显然,这可能或可能不是你想要的。