2013-01-12 41 views
2

我很難定義這個問題。我想要做這樣的事情:如何創建一個接受任何Seq [T,Int]並返回Seq原始類型的函數。

val list = List(("a",1), ("b",2)) 

private def shiftIndex[C <: Seq[_]](seq: C, amount: Int): C = { 
    seq.map({ case (value, integer) => (value, integer + amount) }) 
} 

shiftIndex(list,3) 

應該返回

List(("a",4),("b",5)): List[String,Integer] 

但它應該是最一般的情況下工作:

  1. SEQ實現地圖(我知道它不是:SEQ )
  2. seq存儲任何元組和一個Int。

任何資源鏈接解釋這些概念將不勝感激。

+0

使用http://stackoverflow.com/questions/5410846中解釋的方法(或者如果問題允許,可以使用更簡單的'CanBuildFrom'變體)。 –

回答

5
import scala.collection.generic.CanBuildFrom 
import scala.collection.GenTraversable 
import scala.collection.GenTraversableLike 

def shiftIndex[T, Repr](seq: GenTraversableLike[(T, Int), Repr], amount: Int)(
    implicit bf: CanBuildFrom[Repr, (T, Int), Repr]) = { 
    seq.map { case (value, integer) => (value, integer + amount) } 
} 

shiftIndex(List(("a", 1), ("b", 2)), 3)  // List((a,4), (b,5)) 
shiftIndex(Set(("a", 1), ("b", 2)), 3)  // Set((a,4), (b,5)) 
shiftIndex(Map(("a", 1), ("b", 2)), 3)  // Map(a -> 4, b -> 5) 

雖然我可能會推薦一個更好看,更通用的解決方案。在這裏,我豐富 GenTraversable使得對所有穿越對象都有一個方法mapVals這需要將被施加到所述一對的第二部分的功能,並且具有一個返回鍵入相同的作爲對象它是在運行:

class EnrichedWithMapVals[T, U, Repr](seq: GenTraversableLike[(T, U), Repr]) { 
    def mapVals[R, That](f: U => R)(implicit bf: CanBuildFrom[Repr, (T, R), That]) = { 
    seq.map { case (x, y) => (x, f(y)) } 
    } 
} 
implicit def enrichWithMapVals[T, U, Repr](self: GenTraversableLike[(T, U), Repr]) = new EnrichedWithMapVals(self) 

List(("a", 1), ("b", 2)).mapVals(_ + 3)  // List((a,4), (b,5)) 
Set(("a", 1), ("b", 2)).mapVals(_ + 3)  // Set((a,4), (b,5)) 
Map(("a", 1), ("b", 2)).mapVals(_ + 3)  // Map(a -> 4, b -> 5) 
+0

+1爲一般情況。 –

相關問題