1

最後に終了した場所から始まるバイト配列を読み取ることによってそれぞれが構築されたオブジェクトListのを構築したいと思います。ビルド時に必要な状態はこれまでの内容と読み込んだバイト数だけなので、小さいものを大きいものに変換する関数を繰り返し適用することでこれを行うことを考えていました。各ステップで、 currentがパラメーターとして渡され (および、これに対する再解析を避けるために、これまでに読み取られたバイト数も含まれる場合があります)、要素が追加されて返されます。これは を構築するための非常に簡単な方法のように思えるので、興味はありましたが、これに使用できるライブラリ関数を見つけることができませんでした。以下は、私がやろうとしていることの必須の例です。機能を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)
  }

あなたが期待している Foo の数はわかりませんが、それが 1000 を超える場合は、スタックを爆破しないように、この末尾を再帰的にすることをお勧めします (ヒント: 出力に追加のパラメーターを追加します)。 、デフォルト値Nil)。

于 2012-11-10T10:38:16.530 に答える