Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 逐段懒洋洋地读取文件_Ruby_Lazy Evaluation - Fatal编程技术网

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"]