为什么这个flatMap不能工作?

时间:2013-06-28 07:12:02

标签: scala

我希望在Scala 2.9.3中将(k,v)元组的嵌套列表转换为(v,k)的平面列表。我尝试将所需的函数文字放在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) }
                                                                                      ^

为什么会发生这种情况?

2 个答案:

答案 0 :(得分:3)

您应在此使用flattenmap,而不是flatMap

flatMap上的{p> List[a]需要A => List[B]函数(实际上不是List[B],而是B的任何集合)并返回List[B]。这不是你的情况。

您有一个功能C => B,而不是List[C] => List[B]。在您的情况下,AList[C]

map上的{p> 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))

答案 1 :(得分: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))

基本上你首先展平嵌套列表,然后映射以重新排序元组。