使用多个返回值Vectorize Scala函数

时间:2012-12-05 14:16:15

标签: scala

对返回多个值的scala函数进行矢量化的最优雅方法是什么?

例如,假设我有以下功能:

def Foobar(foo: Int, bar: Int): (Int, Int) = (foo, bar)

如果它返回一个值,我会做这样的事情:

val a = Array(1, 2, 3)
val b = Array(4, 5, 6)
val c = (a,b).zipped.map(foobar)

但是因为它返回一个元组,我最终得到Array[(Int,Int)],而我更喜欢(Array[Int], Array[Int])。做这样的事情的正确方法是什么?是否有任何聪明的模式可以将其概括为:

val c = vectorized(foobar,a,b)

任何想法都会非常感激。谢谢!

2 个答案:

答案 0 :(得分:5)

你可以解压缩它(显然,它与zip相反的操作):

val c = foobar(a,b).unzip
//res2: (s.c.m.IndexedSeq[Int], s.c.m.IndexedSeq[Int]) = (ArrayBuffer(1, 2, 3),ArrayBuffer(4, 5, 6))

但你最终会使用IndexedSeq,而不是Arrays。

答案 1 :(得分:1)

嗯,如果你愿意的话,你当然可以写一个vectorized函数,尽管你需要为每个输入和输出arity提供一个不同的函数。这是2.10版本(2.9将使用Manifest而不是ClassTag)两个输入和两个输出:

import reflect.ClassTag
def vectorized[A, B, C: ClassTag, D: ClassTag](
  f: (A,B) => (C,D), a: Array[A], b: Array[B]
): (Array[C], Array[D]) = {
  val c = Array.newBuilder[C]
  val d = Array.newBuilder[D]
  for (i <- 0 until math.min(a.length, b.length)) {
    val x = f(a(i), b(i))
    c += x._1
    d += x._2
  }
  (c.result, d.result)
}