我将哪些参数传递给 Scala 中的“过滤器”函数

时间:2021-06-05 20:31:22

标签: python scala

我无法理解这段涉及 lambda 表达式的 Scala 代码:

object ScalaList {
  case class Student(rollNo : Int, name : String, marks : Int)
  val students=   List(Student(1,"A",10),Student(2,"B",14))
  var toppers = students.filter(s=>s.marks>10)    //> toppers  : List[ScalaList.Student] = List(Student(2,B,14))
}

它可以工作,但过滤器函数采用我未定义的参数“s”。什么是's'。另外,如果这是熊猫,我想我需要提供一个 axis=1 参数。为什么我在 Scala 中不需要它

2 个答案:

答案 0 :(得分:4)

也许有助于比较 Python 实现

>>> from pydantic import BaseModel
>>>
>>> class Student(BaseModel):
...     rollNo: int
...     name: str
...     marks: int
...
>>> students = [
...     Student(rollNo=1, name="A", marks=10),
...     Student(rollNo=2, name="B", marks=14)
... ]
>>>
>>> list(filter(lambda s: s.marks > 10, students))
[Student(rollNo=2, name='B', marks=14)]

具有类似的 Scala 实现

scala> case class Student(
     |     rollNo: Int,
     |     name: String,
     |     marks: Int
     | )
     | val students = List(
     |     Student(1, "A", 10),
     |     Student(2, "B", 14)
     | )
     | students.filter(s => s.marks > 10)
class Student
val students: List[Student] = List(Student(1,A,10), Student(2,B,14))
val res0: List[Student] = List(Student(2,B,14))

我们看到 Scala lambda 的地方

s => s.marks > 10

类似于 Python lambda

lambda s: s.marks > 10

这应该明确声明的 lambda 参数 s 成为 lambda 主体内的局部变量。

考虑 List#filter 的 Scala API 文档以及 Scala 3 Book 的 Scala for Python Developers 部分。

答案 1 :(得分:3)

请注意,filter 方法的参数不是 s,而是整个 s => s.marks > 10:这是定义匿名函数的语法它接受一些 s 并返回其 marks 字段与文字 10 的比较结果。在这种情况下,s 只是函数参数的组成名称,就像将其定义为方法一样,如下例所示:

def marksGreaterThan10(s: Student): Boolean = s.marks > 10

可能让某人对语法有些困惑的一件事是编译器本身能够根据您的输入推断类型,使其非常紧凑和可读,但对于新手来说可能有点不透明。请注意,如果没有适当的上下文(即过滤 Student 的列表,因此函数的输入类型必须Student),编译器会抱怨missing parameter type 并且您需要提供一个,如下例所示(我将匿名函数分配给一个变量,以便我可以在程序的其他部分使用它):

val marksGreaterThan10 = (s: Student) => s.marks > 10

请注意,方法和函数都可以传递给高阶函数(可以将函数作为参数或返回一个函数作为输出的函数),例如 {{1} }.

filter

您可以在 Scastie 上使用上面的代码 here

如果您熟悉 Java lambda 表达式 语法,final case class Student(marks: Int) val marksGreaterThan10Function = (s: Student) => s.marks > 10 def marksGreaterThan10Method(s: Student): Boolean = s.marks > 10 val students = Seq(Student(1), Student(11)) // Both of these returns `Seq(Student(11))` students.filter(marksGreaterThan10Function) students.filter(marksGreaterThan10Method) 或多或少等价于 ->,并且您会编写如下代码:

=>
相关问题