使用 filter() 方法在 Scala 中查找以数字开头的行

Finding lines that start with a digit in Scala using filter() method

我是一名 python 程序员,由于 Python API 对于我的 Spark 应用程序来说太慢了,因此决定将我的代码移植到 Spark Scala API,以比较计算时间。

我试图在 Spark 中使用 Scala API 从一个巨大的文件中过滤掉以数字字符开头的行。在我的文件中,有些行有数字,有些有文字,我想要只有数字的行。

因此,在我的 Python 应用程序中,我有这些行。

l = sc.textFile("my_file_path")
l_filtered = l.filter(lambda s: s[0].isdigit())

完全符合我的要求。

这是我目前尝试过的方法。

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(x => x.forall(_.isDigit))

这会抛出一个错误,指出 char 没有 forall() 函数。

我还尝试使用 s.take(1) 获取行的第一个字符,并按以下方式对其应用 isDigit() 函数。

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(x => x.take(1).isDigit)

还有这个……

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(x => x.take(1).Character.isDigit)

这也会引发错误。

这基本上是一个小错误,由于我不习惯 Scala 语法,所以我很难弄清楚。任何帮助将不胜感激。

编辑:正如对此 question 的回答,我尝试编写该函数,但我无法在我的应用程序的 filter() 函数中使用它。 为文件中的所有行应用函数。

在 Scala 中,索引语法使用圆括号 () 而不是方括号 []。您的 Python 代码的准确翻译是这样的:

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(_(0).isDigit)

第一个符号的更惯用的提取方法是使用 head 方法:

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(_.head.isDigit)

如果您的文件包含空行,这两种方法都会失败。

如果是这样,那么您可能想要这个:

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(_.headOption.map(_.isDigit).getOrElse(false))

UPD.

正如 好奇Option 上指出的 map(predicate).getOrElse(false) 可以缩短为 exists(predicate):

val l = sc.textFile("my_file_path")
val l_filtered = l.filter(_.headOption.exists(_.isDigit))

您可以使用正则表达式:

scala> List("1hello","2world","good").filter(_.matches("^[0-9].*$"))
res0: List[String] = List(1hello, 2world)

或者你可以用较小的号来这样做。操作,因为此文件可能包含大量要过滤的行。

scala> List("1hello","world").filter(_.headOption.exists(_.isDigit))
res1: List[String] = List(1hello)

List[String] 替换为你的行 l 在你的情况下工作。