1

一連の注文を処理する必要があります (ここIntでは簡略化のために):

// the handleOrder methods are in fact much more complicated:
def handleOrders(prev: Double, orders: Seq[Int]): Double = prev + orders.sum
def handleOrder(prev: Double, order: Int): Double = prev / order

いわゆる

def nextGroup(prev: Double, orders: Seq[Int]): Seq[Double]

function 別のクラスのシーケンスを取得します (ここDoubleでは簡略化のために)。

これから、2つのバージョンを実装しました。

バージョン 1 (foldLeft および明示的なビルダー):

def nextGroup1(prev: Double, orders: Seq[Int]): Seq[Double] = {
  import collection.mutable.Builder
  import collection.immutable.VectorBuilder
  val bld: Builder[Double, Seq[Double]] = new VectorBuilder[Double]
  var first = true
  orders.foldLeft(prev) { (prev, order) =>
    val step = if (first) handleOrders(prev, orders) else prev
    val next = handleOrder(step, order)
    first = false
    bld += next
    next
  }
  bld.result
}

バージョン 2 (var および yield builder 用):

def nextGroup2(prev: Double, orders: Seq[Int]): Seq[Double] = {
  var first = true
  var präv = prev
  for (order <- orders) yield {
    if (first) präv = handleOrders(präv, orders)
    präv = handleOrder(präv, order)
    first = false
    präv
  }
}

varバージョン 1 で明示的なビルダーを保存するか、バージョン 2 でミュータブルを保存したいと思います。

これは可能ですか?foldLeftおそらく、とfor-の組み合わせでyield

そしてまだ何かサンプルデータ:

val orders = Seq(1, 2, 3)
nextGroup1(1d, orders) // => Vector(7.0, 3.5, 1.1666666666666667)
nextGroup2(1d, orders) // => List(7.0, 3.5, 1.1666666666666667)
nextGroup1(2d, orders) // => Vector(8.0, 4.0, 1.3333333333333333)
nextGroup2(2d, orders) // => List(8.0, 4.0, 1.3333333333333333)

nextGroupとして扱われる結果は、Seq[Double]そうでVectorあろListうとなかろうと違いはありません。

4

1 に答える 1

6
orders.tail.scanLeft(handleOrders(prev, orders)) { (p, o) => handleOrder(p, o) }

scanLeftと同じことをfoldLeft行いますが、すべての中間結果を保持します。headを使用して実行できるコレクションを除外することで、特殊なケースを取り除くことができますorders.tail

于 2011-11-22T18:43:49.133 に答える