我正在尝试过滤掉第二列值以列表中的单词开头的文本文件的行。
我有以下列表:
val mylist = ["Inter", "Intra"]
如果我有一行:
Cricket Inter-house
Inter
位于列表中,因此该行应该被RDD.filter
操作过滤掉。我正在使用以下正则表达式:
`[A-Za-z0-9]+`
我尝试使用"""[A-Za-z0-9]+""".r
来提取子字符串,但结果是在非空的迭代器中。
我的问题是如何在过滤操作中访问上述结果?
答案 0 :(得分:0)
filter
将删除传递给filter
方法的函数返回true
的任何内容。因此,正则表达并不是你想要的。相反,让我们开发一个函数,它接受一行并将其与候选字符串进行比较,如果该行中的第二列以候选字符串开头,则返回true
:
val filterFunction: (String, String) => Boolean =
(row, candidate) => row.split(" ").tail.head.startsWith(candidate)
我们可以说服自己,使用工作表非常容易:
// Test data
val mylist = List("Inter", "Intra")
val file = List("Cricket Inter-house", "Boom Shakalaka")
filterFunction("Cricket Inter-house", "Inter") // true
filterFunction("Cricket Inter-house", "Intra") // false
filterFunction("Boom Shakalaka", "Inter") // false
filterFunction("Boom Shakalaka", "Intra") // false
现在剩下的就是在过滤器中使用此功能。基本上,对于每一行,我们都希望针对候选列表中的每一行测试过滤器。这意味着获取候选列表并“向左折叠”以针对该功能检查其上的每个项目。如果任何候选人报告为真,那么我们知道该行应该从最终结果中过滤掉:
val result = file.filter((row: String) => {
!mylist.foldLeft(false)((x: Boolean, candidate: String) => {
x || filterFunction(row, candidate)
})
})
// result: List[String] = List(Boom Shakalaka)
以上打开时可能会有点密集。我们向filter
方法传递一个接受一行并产生一个布尔值的函数。当且仅当行与我们的条件不匹配时,我们希望该值为true
。我们已经在filterFunction
中嵌入了我们的标准:我们只需要针对mylist
中的每个项目组合运行它。
为此,我们使用foldLeft
,它取一个起始值(在本例中为false
)并迭代地遍历列表,更新该起始值并返回最终结果。
为了“更新”该值,我们编写了一个函数,该函数逻辑地将起始值与运行我们的过滤函数的结果相对于mylist
中的行和当前项运行。
答案 1 :(得分:0)
您需要构建正则表达式,例如".* Inter.*".r
,因为"""[A-Za-z0-9]+"""
匹配任何单词。这是一些工作示例,希望它有所帮助:
val mylist = List("Inter", "Intra")
val textRdd = sc.parallelize(List("Cricket Inter-house", "Cricket Int-house",
"AAA BBB", "Cricket Intra-house"))
// map over my list to dynamically construct regular expressions and check if it is within
// the text and use reduce to make sure none of the pattern exists in the text, you have to
// call collect() to see the result or take(5) if you just want to see the first five results.
(textRdd.filter(text => mylist.map(word => !(".* " + word + ".*").r
.pattern.matcher(text).matches).reduce(_&&_)).collect())
// res1: Array[String] = Array(Cricket Int-house, AAA BBB)