使用 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
在你的情况下工作。
我是一名 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
在你的情况下工作。