我有一张地图
val m = Map(1->2, 3->4, 5->6, 7->8, 4->4, 9->9, 10->12, 11->11)
Run Code Online (Sandbox Code Playgroud)
现在我想要一个其键等于值的地图.所以我这样做
def eq(k: Int, v: Int) = if (k == v) Some(k->v) else None
m.flatMap((k,v) => eq(k,v))
Run Code Online (Sandbox Code Playgroud)
这给了我错误
error: wrong number of parameters; expected = 1
m.flatMap((k,v) => eq(k,v))
Run Code Online (Sandbox Code Playgroud)
上述代码有什么问题?flatMap期待一个参数函数,这里我传递一个参数,它是一对整数.
这也有效
m.flatMap {
case (k,v) => eq(k,v)
}
Run Code Online (Sandbox Code Playgroud)
但事实并非如此
m.flatMap {
(k,v) => eq(k,v)
}
Run Code Online (Sandbox Code Playgroud)
看起来我错过了一些东西.救命?
没有这样的语法:
m.flatMap((k,v) => eq(k,v))
Run Code Online (Sandbox Code Playgroud)
嗯,实际上有这样的语法,但实际上它用在接受两个参数的函数中(比如reduce):
List(1,2,3,4).reduce((acc, x) => acc + x)
Run Code Online (Sandbox Code Playgroud)
该
m.flatMap {
case (k,v) => eq(k,v)
}
Run Code Online (Sandbox Code Playgroud)
语法有效,因为事实上它是这样的:
val temp: PartialFunction[Tuple2[X,Y], Tuple2[Y,X]] = {
case (k,v) => eq(k,v) // using literal expression to construct function
}
m.flatMap(temp) // with braces ommited
Run Code Online (Sandbox Code Playgroud)
他们关键的一点是这个case词的用法(实际上,有一个讨论可以启用你的语法),这会转换为常用的大括号表达式,就像{ ... }成为完整的匿名部分函数一样
(如果你想简单地修复你得到的错误,请参阅第二个解决方案(带flatMap);如果你想要一个更好的解决方案,请从头开始阅读.)
你所需的是filter不是flatMap:
def eq(k: Int, v: Int) = k == v
val m = Map(1->2, 3->4, 5->6, 7->8, 4->4, 9->9, 10->12, 11->11)
m.filter((eq _).tupled)
Run Code Online (Sandbox Code Playgroud)
...当然减少到以下几点,而不需要eq:
m.filter { case (k, v) => k == v }
Run Code Online (Sandbox Code Playgroud)
结果:
Map(9 -> 9, 11 -> 11, 4 -> 4)
Run Code Online (Sandbox Code Playgroud)
或者......如果你想坚持下去 flatMap
首先,您必须知道flatMap将传递给您的函数TUPLES而不是键和值作为单独的参数.
此外,您必须将Option返回的内容更改为eq可以反馈到flatMap序列上的内容,例如List或Map(实际上GenTraversableOnce要精确):
def eq(k: Int, v: Int) = if (k == v) List(k -> v) else Nil
m.flatMap { case (k,v) => eq(k,v) } // use pattern matching to unpack the tuple
Run Code Online (Sandbox Code Playgroud)
或丑陋但相当于:
m.flatMap { x => eq(x._1, x._2) }
Run Code Online (Sandbox Code Playgroud)
或者,您可以转换eq为取代元组:
m.flatMap((eq _).tupled)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1954 次 |
| 最近记录: |