我目前正在学习Scala,并且很难在zip
ped集合上使用占位符语法。例如,我想从l2 [i]> = l1 [i]的项目中过滤压缩数组。如何使用显式函数文字或占位符语法执行此操作?我试过了:
scala> val l = List(3, 0, 5) zip List(1, 2, 3)
l: List[(Int, Int)] = List((3,1), (4,2), (5,3))
scala> l.filter((x, y) => x > y)
<console>:9: error: missing parameter type
Note: The expected type requires a one-argument function accepting a 2-Tuple.
Consider a pattern matching anonymous function, `{ case (x, y) => ... }`
l.filter((x, y) => x > y)
^
<console>:9: error: missing parameter type
l.filter((x, y) => x > y)
scala> l.filter((x:Int, y:Int) => x > y)
<console>:9: error: type mismatch;
found : (Int, Int) => Boolean
required: ((Int, Int)) => Boolean
l.filter((x:Int, y:Int) => x > y)
尝试使用占位符语法:
scala> l.filter(_ > _)
<console>:9: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$greater(x$2))
Note: The expected type requires a one-argument function accepting a 2-Tuple.
Consider a pattern matching anonymous function, `{ case (x$1, x$2) => ... }`
l.filter(_ > _)
^
<console>:9: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$greater(x$2))
l.filter(_ > _)
所以似乎需要Pair
上的函数:
scala> l.filter(_._1 > _._2)
<console>:9: error: missing parameter type for expanded function ((x$1, x$2) => x$1._1.$greater(x$2._2))
Note: The expected type requires a one-argument function accepting a 2-Tuple.
Consider a pattern matching anonymous function, `{ case (x$1, x$2) => ... }`
l.filter(_._1 > _._2)
^
<console>:9: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1._1.$greater(x$2._2))
l.filter(_._1 > _._2)
那么我做错了什么? match
是唯一的方式吗?谢谢你的帮助。
答案 0 :(得分:5)
使用此:
l.filter { case (x, y) => x > y }
或
l.filter(x => x._1 > x._2)
同样在Scala中,从函数体到其参数的类型信息does not flow。
答案 1 :(得分:1)
当您发现filter
超过List
时需要一个只有一个参数的函数(在您的情况下为Tupple2
又称&#34;对&#34;):
def filter(p: (A) => Boolean): List[A]
此(x, y) => x > y
表示具有两个参数(A, B) => Boolean
的函数。因此,您使用_1
和_2
朝着正确的方向前进,但每次使用_
代表一个新参数,因此_._1 > _._2
实际上等同于(x, y) => x._1 > y._2
。因此,如果您想多次使用相同的参数,则不能使用下划线:
l.filter(p => p._1 > p._2)
另一种可能性是使用模式匹配来扩展Tupple2
:
l.filter{ case (x, y) => x > y }
或者,您可以使用zipped
返回Tuple2Zipped
,其过滤器接受带有两个参数的函数(下面简化签名):
def filter(f: (El1, El2) => Boolean): (List[El1], List[El2])
您可以这样使用zipped
:
scala> val l = (List(3, 0, 5), List(1, 2, 3)) zipped
l: scala.runtime.Tuple2Zipped[Int,List[Int],Int,List[Int]] = scala.runtime.Tuple2Zipped@8dd86903
scala> l.filter(_ > _)
res1: (List[Int], List[Int]) = (List(3, 5),List(1, 3))
scala> l.filter(_ > _).zipped.toList
res2: List[(Int, Int)] = List((3,1), (5,3))
filter
的{{1}}会返回一对列表而不是一对列表,因此要转换为第二种形式,您可以使用Tuple2Zipped
。