gpt4 book ai didi

scala - 如何编写被枚举者沿不同边界对枚举器进行分块

转载 作者:行者123 更新时间:2023-12-04 11:56:48 26 4
gpt4 key购买 nike

所以 Play2.0 Enumeratee page显示了使用 &> 的示例或 through更改 Enumerator[String] 的方法成Enumerator[Int] :

val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt

还有一个 Enumeratee.grouped enumeratee 从单个元素创建块的枚举器。这似乎工作正常。

但我看到的是通常的输入形式是 Array[Byte] (由 Enumerator.fromFileEnumerator.fromStream 返回)。考虑到这一点,我想把那些 Array[Byte]输入并将它们转换为 Enumerator[String] ,例如每个字符串都是一行(以 '\n' 结尾)。线条和 Array[Byte] 的边界元素通常不会匹配。如何编写可以将分块数组转换为分块字符串的枚举器?

目的是将这些行作为每个 Array[Byte] 分块回浏览器。变得可用,并保留不属于完整行的剩余字节,直到下一个输入块出现。

理想情况下,我希望有一种方法可以给出 iter: Iteratee[Array[Byte], T]和一个 Enumerator[Array[Byte]]会给我回一个 Enumerator[T] ,其中我的 T 元素由 iter 解析.

附加信息:我有一些时间来清理我的代码,这是我正在尝试做的一个具体示例。我有以下迭代器检测下一行:
import play.api.libs.iteratee._
type AB = Array[Byte]

def takeWhile(pred: Byte => Boolean): Iteratee[AB, AB] = {
def step(e: Input[AB], acc: AB): Iteratee[AB, AB] = e match {
case Input.EOF => Done(acc, Input.EOF)
case Input.Empty => Cont(step(_, acc))
case Input.El(arr) =>
val (taking, rest) = arr.span(pred)
if (rest.length > 0) Done(acc ++ taking, Input.El(rest))
else Cont(step(_, acc ++ taking))
}
Cont(step(_, Array()))
}

val line = for {
bytes <- takeWhile(b => !(b == '\n' || b == '\r'))
_ <- takeWhile(b => b == '\n' || b == '\r')
} yield bytes

我想做的是这样的事情:
Ok.stream(Enumerator.fromFile(filename) &> chunkBy(line)).as("text/plain")

最佳答案

https://github.com/playframework/Play20/commit/f979006a7e2c1c08ca56ee0bae67b5463ee099c1#L3R131做一些类似于你正在做的事情。我修复了分组以处理剩余的输入。代码基本上如下所示:

val upToNewLine = 
Traversable.splitOnceAt[String,Char](_ != '\n') &>>
Iteratee.consume()

Enumeratee.grouped(upToNewLine)

我也必须以同样的方式修复重复

关于scala - 如何编写被枚举者沿不同边界对枚举器进行分块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10346592/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com