2012-12-05 46 views
3

向量化返回多個值的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) 

任何想法將不勝感激。謝謝!

回答

5

你可以將它解壓縮(很明顯,它的操作是oposite到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)) 

但是你會IndexedSeqs,不是數組結束。

1

那麼,如果你願意,你當然可以寫一個vectorized函數,儘管你需要一個不同的輸入輸出元素。下面是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) 
} 
+0

你可以使用*無形*? – ziggystar

+0

@ziggystar - 你爲什麼?無形是爲了最大的功率而設計的,而不是性能!你可以使用debox。 –

+0

你可能是正確的,你不會得到一個無形的解決方案,以避免拳擊。您的解決方案是否將參數設置爲「f」? – ziggystar