2013-06-28 67 views
1

我想要一個嵌套列表(k,v)元組轉換爲Scala 2.9.3中的(v,k)的平面列表。我試圖把所需的函數文字放在flatMap中。但是,發生這種情況:爲什麼不能使用flatMap工作?

scala> List(List((1,"123"), (1,"abc")), List((45, "qwer"))).flatMap{ case (k,v) => (v,k) } 
<console>:16: error: constructor cannot be instantiated to expected type; 
found : (T1, T2) 
required: List[(Int, java.lang.String)] 
     List(List((1,"123"), (1,"abc")), List((45, "qwer"))).flatMap{ case (k,v) => (v,k) } 
                      ^
<console>:16: error: not found: value v 
     List(List((1,"123"), (1,"abc")), List((45, "qwer"))).flatMap{ case (k,v) => (v,k) } 
                         ^
<console>:16: error: not found: value k 
     List(List((1,"123"), (1,"abc")), List((45, "qwer"))).flatMap{ case (k,v) => (v,k) } 
                        ^

這是爲什麼發生在我身上?

回答

3

您應該使用flattenmap這裏,而不是flatMap

flatMapList[a]需要功能A => List[B](其實不是List[B],但B任何集合),並返回List[B]。這不是你的情況。

你有一個功能C => B,而不是List[C] => List[B]。在你的情況下,AList[C]

map on List[A]採用函數A => B並返回List[B]

val listOfLists = List(List((1,"123"), (1,"abc")), List((45, "qwer"))) 
listOfLists.flatten.map{ case (k,v) => (v,k) } 
// List[(String, Int)] = List((123,1), (abc,1), (qwer,45)) 

你可以使用flatMap,但List[List[A]]你必須提供一個函數,它List[A]作爲這樣一個論點:

listOfLists.flatMap(_.map{case (k,v) => (v,k)}) 
// List[(String, Int)] = List((123,1), (abc,1), (qwer,45)) 
+0

同樣的錯誤,當我在2.9.3 repl上做的時候 – aitchnyu

+0

@aitchnyu:我沒有注意到你有'List [List [A]]'。固定。再試一次。 – senia

+0

這解釋了一切!我的要求甚至沒有在這個問題上,因爲我使用Spark分佈式集合,它有類似的Scala集合的API(我用List重現了我的問題)。 – aitchnyu

1

這將工作:

scala> val m = List(List((1,"123"), (1,"abc")), List((45, "qwer"))) 
m: List[List[(Int, java.lang.String)]] = List(List((1,123), (1,abc)), List((45,qwer))) 

scala> m.flatten.map { case (k,v) => (v,k) } 
res0: List[(java.lang.String, Int)] = List((123,1), (abc,1), (qwer,45)) 

基本上你首先扁平化嵌套列表,然後映射重新排列元組。