我想知道更有效的方法来仅读取基于特定长度的文件字符串。我知道这是一种天真的方法:
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
我想知道更有效的方法来仅读取基于特定长度的文件字符串。我知道这是一种天真的方法:
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
这将与您的代码相同。
d = File.open("d.txt").lines.select{|l| l.chomp.length == len}
这有很多问题:
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
首先,由于 将整个文件读入内存File.open('d.txt').read
,然后使用 分割成行each_line
,最后捕获所需长度的行。如果文件由 1,000,000 行组成,并且只有一个是三个字符长,则会浪费大量内存和 CPU 时间。
相反,这样写:
len = 3
d = []
File.foreach('d.txt') do |x|
d << x if (x.chomp.length == len)
end
foreach
读取每一行,保持换行符。chomp
删除换行符,因此您可以比较实际行,由于chomp
, 到len
. 然后,如果长度匹配,则该行将附加到数组中。除非每一行都是所需的长度,否则整个文件都不会在内存中。这样可以节省内存,并且运行速度非常快,甚至可能比用于read
slurp 整个文件的原始速度更快,因为如果文件足够大,该过程可能需要一段时间。