1

我想构建一个对象,每个对象都是通过从最后一个完成的位置开始读取一个字节数组来构建List的。鉴于构建时唯一需要的状态是到目前为止的内容和读取的字节数,我正在考虑通过重复应用一个将较小的函数转换为较大的函数来做到这一点。在每个步骤中,当前都作为参数传递(可能是到目前为止读取的字节数以避免为此重新解析)并返回附加元素。由于这似乎是一种非常简单的构建方法,因此我很感兴趣,但未能成功找到可用于此的库函数。以下是我正在尝试做的必要示例,我想在FooFooListListListbytesToList无状态更简洁:

def bytesToList(bytes: Array[Byte]): List[Foo] =
{
  var numBytesRead = 0
  var listToBuild = List[Foo]()
  while (numBytesRead < bytes.length)
  {
    listToBuild ::= new Foo(bytes, numBytesRead)
    numBytesRead += listToBuild.last.bytesRead
  }
  listToBuild
}

class Foo(bytesToRead: Array[Byte], startReadingAt: Int)
{val bytesRead = Random.nextInt(bytesToRead.length)}
4

2 回答 2

3

我的又快又脏?解决方案在这里:

//some random source for bytes
def bytes(count: Int): Stream[Byte] = {
    var byteArray: Array[Byte] = new Array(count)
    Random.nextBytes(byteArray)
    (for {i <- (0 to count-1) } yield byteArray(i)).toStream
} 

class Foo(b1: Byte, b2: Byte, pb: (Byte, Byte)) {
    def this(bytes4foo: Array[Byte]) = this( bytes4foo(0), bytes4foo(1), (bytes4foo(2), bytes4foo(3)) )
    def sizeOf: Int = 4
    override def toString = "Foo("+b1+", "+b2+", "+pb+")"
}

def bytesToList(source: Stream[Byte]): List[Foo] = {
  val afoo = new Foo(0,0,(0,0)) // ~ static Foo.sizeOf
  def moreFoo(next: Stream[Byte]): List[Foo] = {
    if (next == Stream.Empty) Nil
    else new Foo(source.take(afoo.sizeOf).toArray) :: bytesToList(source.drop(afoo.sizeOf))
  }
  moreFoo(source)
}                                        

测试它:

bytesToList(bytes(20)) mkString "\n"    
//> res1: String = Foo(-73, 63, (-14,107))
               //| Foo(-61, 105, (-124,-44))
               //| Foo(117, 79, (-79,-17))
               //| Foo(-84, -116, (13,-3))
               //| Foo(93, -110, (30,36))  
于 2012-11-10T10:19:31.150 回答
3

如果您不能事先拆分数组,则需要使用显式递归,例如:

def bytesToList(bytes: Array[Byte], n: Int = 0): List[Foo] = 
  if (n >= bytes.length) Nil
  else {
    val foo = new Foo(bytes, n) 
    foo :: bytesToList(bytes, n + foo.bytesRead)
  }

我不知道你期望 Foos 有多少,但如果它超过一千个左右,最好使这个尾递归以避免炸毁堆栈(提示:为输出添加一个额外的参数,默认值Nil)。

于 2012-11-10T10:38:16.530 回答