2016-08-16 98 views
1

我有一个名为name的RDD。Scala RDD字符串操作

scala> name 
res6: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[24] at map at <console>:37 

我可以用name.foreach(println)

name5000005125651330 
name5000005125651331 
name5000005125651332 
name5000005125651333 

我希望创建一个新的RDD,可以消除每个记录的开始name字符和long格式返回剩余的号码检验。

期望的结果:

5000005125651330 
5000005125651331 
5000005125651332 
5000005125651333 

我曾尝试以下:

val name_clean = name.filter(_ != "name") 

然而,这将返回:

name5000005125651330 
name5000005125651331 
name5000005125651332 
name5000005125651333 
+0

“不过这将返回”嗯,当然,因为每行不等于“名”差不多吧。 'name.map(_。drop(4).toLong)'应该这样做(仅仅是放弃前四个字符无条件地,它不检查他们是否是一个。 –

+0

谢谢保罗。我没有意识到这一点。成功了!随意发布作为答案 – LearningSlowly

回答

4

在RDD每一项都是一个字符串。因此,将它与“名称”进行比较将总是失败,因为它是“名称”+一些数字。

您需要的是map迭代RDD并返回每个条目的新值。新的值应该是字符串,没有前4个字符,并将其转换为Long。

把所有在一起,我们得到

name.map(_.drop(4).toLong) 

如果你不知道的前四个字符将是“名”,你可能要检查的是第一个。你需要什么,然后取决于你想与没有名字的第一个四行做什么,而是要像

name.filter(_.startsWith("name")).map(_.drop(4).toLong) 
2

方法stripPrefix将删除从字符串中给定的前缀(如果什么都不做字符串不与前缀开头

所以你实现你所需要的人:

val name_clean = name.map(_.stripPrefix("name").toLong) 
+0

只有OP知道肯定,但似乎不太可能,如果前四个字符不是“名称”,那么他们将是数字。所以如果文件只包含起始“名称”的行,这可以工作(但你可能只需放下四个字符)。如果某些行不能启动“名称”,这可能会引发错误。 –

+0

是的。但是根据上下文,人们可能更喜欢运行时错误来默默地忽略错误的条目。如果想要忽略忽略,那么我们可以插入'.filter(_。startsWith(“name”))''就像在你的答案中一样。 –

+0

对不起。不可以。根据错误行是否只包含数字,您的代码可能只会发出异常。可能或者可能不会例外对不好的输入不好 –