2

我目前正在学习 Scala,并且一直在努力在zipped 集合上使用占位符语法。例如,我想从 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(_ > _)

所以它似乎需要一个函数 a 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方式是唯一的吗?谢谢您的帮助。

4

2 回答 2

5

用这个:

l.filter { case (x, y) => x > y }

或者

l.filter(x => x._1 > x._2)

同样在 Scala 中,类型信息不会从函数体流向其参数。

于 2015-08-10T23:33:03.850 回答
1

正如您发现的那样filterList需要一个只有一个参数的函数(在您的情况下是一个Tupple2又名“Pair”):

def filter(p: (A) => Boolean): List[A]

(x, y) => x > y意味着一个有两个参数的函数(A, B) => Boolean。因此,您在使用_1and时朝着正确的方向前进_2,但是每次使用 of 都_代表一个新参数,因此_._1 > _._2实际上等效于(x, y) => x._1 > y._2. 因此,如果您想多次使用相同的参数,则不能使用下划线:

l.filter(p => p._1 > p._2)

另一种可能性是使用模式匹配来扩展Tupple2

l.filter{ case (x, y) => x > y }

或者,您可以使用zippedwhich 将返回 aTuple2Zipped并且其过滤器接受具有两个参数的函数(下面的简化签名):

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))

filterofTuple2Zipped返回一对列表而不是一对列表,因此要转换为第二种形式,您可以使用.zipped.toList.

于 2015-08-11T14:25:38.670 回答