使用filter()方法

时间:2015-09-25 18:32:17

标签: scala syntax apache-spark

我是一名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()函数中使用它。 为文件中的所有行应用此功能。

2 个答案:

答案 0 :(得分:6)

在Scala索引语法中使用parens ()而不是括号[]。您的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。

好奇的注明map(predicate).getOrElse(false)上的Option可以缩短为exists(predicate)

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

答案 1 :(得分:2)

您可以使用正则表达式:

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行。