Ruby 逐段懒洋洋地读取文件
我将一些数据存储在一个文件中,其中每个感兴趣的块存储在一个段落中,如下所示:Ruby 逐段懒洋洋地读取文件,ruby,lazy-evaluation,Ruby,Lazy Evaluation,我将一些数据存储在一个文件中,其中每个感兴趣的块存储在一个段落中,如下所示: hello there kind people of stack overflow 我试着用以下代码阅读每一段,但不起作用: paragraphs = File.open("hundreds_of_gigs").lazy.to_enum.grep(/.*\n\n/) do |p| puts p end 对于正则表达式,我试图说:“匹配以两个换行符结尾的任何内容” 我做错了什么 任何懒散的解决方法都值得赞
hello
there
kind
people
of
stack
overflow
我试着用以下代码阅读每一段,但不起作用:
paragraphs = File.open("hundreds_of_gigs").lazy.to_enum.grep(/.*\n\n/) do |p|
puts p
end
对于正则表达式,我试图说:“匹配以两个换行符结尾的任何内容”
我做错了什么
任何懒散的解决方法都值得赞赏。方法越简洁越好。自定义解决方案。如果
IO#readline(sep)
为您做了@ascar所示的工作,就使用它
grouped_lines = open("file.txt").each_line.lazy.map(&:chomp).chunk(&:empty?)
paragraphs = grouped_lines.map { |sep, lines| lines if !sep }.reject(&:nil?)
p paragraphs
#=> <Enumerator::Lazy: #<Enumerator::Lazy:...
p paragraphs.to_a
#=> [["hello", "there"], ["kind"], ["people", "of"], ["stack", "overflow"]]
grouped_line=open(“file.txt”).each_line.lazy.map(&:chomp).chunk(&:empty?)
段落=分组的_lines.map{sep,lines | lines if!sep}。拒绝(&:nil?)
p段
#=>会做你想做的事File
是IO
的一个子类,它拥有所有的方法,即使它们没有在文件rubydoc页面上说明
它逐行读取,其中行尾是给定的分隔符
例如:
每次调用readline lazy都会从顶部开始读取文件的一行
或者您可以使用来迭代文件
例如:
下面是一个惰性方法,当段落被一行或多行空行分隔时,它可以工作。我认为其他解决方案不允许段落之间的间隔可变
代码
def paragraphs(fname)
complete = true
IO.foreach(fname).with_object([]) do |l,a|
if l.size > 1
if complete
a << l
complete = false
else
a[-1] << l
end
else
complete = true
end
end
end
str = "hello\nthere\n\nkind\n\n\npeople\nof\n\n\n\n\nstack\noverflow"
fname = 'tmp'
File.write(fname, str)
paragraphs(fname)
#=> ["hello\nthere\n", "kind\n", "people\nof\n", "stack\noverflow"]
这里介绍了非惰性方法:File\u每行
都能完全满足您的需要。呃,我很确定它只读行而不读段落。@如果不打开它,只需将“\n\n”作为参数传递,这看起来是最简单的方法。问题:如果有两个以上的“\n”?分隔符基本上可以是任何东西,您甚至可以动态更改它。没有限制。它只读取一行,直到找到分隔符或EOF。下一个调用甚至可以是另一个单独的调用。如果该示例中有4个,您将得到一个空段落。对于前蟒蛇学家:“\n\n”!=”\n\n'@TheUnfunCat'\n\n'=“\\n\\n”单引号将反斜杠视为文字
def paragraphs(fname)
complete = true
IO.foreach(fname).with_object([]) do |l,a|
if l.size > 1
if complete
a << l
complete = false
else
a[-1] << l
end
else
complete = true
end
end
end
str = "hello\nthere\n\nkind\n\n\npeople\nof\n\n\n\n\nstack\noverflow"
fname = 'tmp'
File.write(fname, str)
paragraphs(fname)
#=> ["hello\nthere\n", "kind\n", "people\nof\n", "stack\noverflow"]