给出一个像“苹果从树上掉下来”这样的字符串,我该如何分割它,以便每个单词都附加一行文字,这样我得到的字符串的RDD如下:
"The | The apple fell from a tree"
"apple | The apple fell from a tree"
"fell | The apple fell from a tree"
"from | The apple fell from a tree"
"a | The apple fell from a tree"
"tree | The apple fell from a tree"
这将使我能够跟踪单词的来源。
这是我写的(相关部分)
var inputPath = /path/to/file.txt // Some txt file
var input = sc.textFile(inputPath) // RDD of lines of text
var words = input.flatMap(line => line.split(" ").foreach(word => word.concat(" | " + line))
此代码示例不起作用,因为据我了解,您不能多次在flatMap中遍历吗?我相信我说Found: Unit Required: TraversableOnce[?]
时遇到错误,我是Spark,Scala和函数式编程的新手。第一次编写scala时,我并不担心性能或最短的代码量。我只是希望某些工作而不必重新设计我的实现。我以后总是可以重构。
我知道textFile()给了我一个RDD,其中的Strings代表了文本的每一行。 flatMap用“”拆分这些行,由于它是flatMap,所以我们得到一个数组,而不是一堆数组。如果我错了,或者说话不正确,请纠正我。
答案 0 :(得分:0)
我手头没有火花,因此无法立即确认,但查看代码和错误消息,很可能只是foreach
。
因此,快速解决方法(可能)是将最后一行替换为
input.flatMap(line => line.split(" ").map(word => word.concat(" | " + line))
说明:
line.split
给您一个Array[String]
,我认为它是实例Traversable[String]
foreach
对每个项目应用一个函数,但返回一个Unit
-这意味着调用没有返回值(实际上,它是Unit
类型的单例实例,但如果有帮助,您可以将其视为Java术语中的void
)map
还将函数应用于每个项目,但是返回包含更新后的项目的新Traversable
(可能具有不同的具体类型)。flatMap
是一种本质上将map
和flatten
结合在一起的方法-即,它采用一个接受某项并返回Traversable[OtherType]
的函数,将该函数应用于每个项目,然后通过串联内部可遍历来“展平”结果Traversable[Traversable[OtherType]]
。因此,您需要给它String => Traversable[String]
,但您要传递String => Unit
有关更多信息,请参阅Scala Traversable docs。
在普通字符串列表上的类似代码:
scala> List(
"line1 word1 word2",
"line2 word3 word4"
)
.flatMap(line => line.split(" ").map(word => s"$word | $line"))
res5: List[String] = List(
line1 | line1 word1 word2,
word1 | line1 word1 word2,
word2 | line1 word1 word2,
line2 | line2 word3 word4,
word3 | line2 word3 word4,
word4 | line2 word3 word4
)
顺便说一句,Scala鼓励不变性,因此您可能想使用val
而不是var
,除非您真的想重新分配值-val
或多或少与{ {1}}。在您的代码示例中,可以肯定地用final
替换var
。