用Scala生成简单密钥

用Scala生成简单密钥,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我有一个文件,上面逐行写着如下文字: plane car motorbike truck boat ... 我试图编写一个Scala程序,从文件中读取值,并将每个单词映射到一个键、值对,其中键将是一个整数,随着每个值的增加而递增。我写了以下内容: val vocabFile = sc.textFile("file:///vocab.txt") val vocabIndex=0; val vocabs = vocabFile.map(x => (vocabIndex+=1, x)) 但我

我有一个文件,上面逐行写着如下文字:

plane
car
motorbike
truck
boat
...
我试图编写一个Scala程序,从文件中读取值,并将每个单词映射到一个键、值对,其中键将是一个整数,随着每个值的增加而递增。我写了以下内容:

val vocabFile = sc.textFile("file:///vocab.txt")
val vocabIndex=0;
val vocabs = vocabFile.map(x => (vocabIndex+=1, x))
但我得到了以下错误:

<console>:31: error: value += is not a member of Int
     val vocabs = vocabularyFile.map(x => (vocabIndex+=1, x))

有没有办法不使用循环直接生成这样的对?

您需要能够将新值重新分配给vocabIndex,因此它应该是一个变量:

此外,Scala中的赋值结果是单位,而不是Java中的赋值。因此,您需要将代码分解为:

vocabFile.map(x => { val e = (vocabIndex, x); vocabIndex += 1; e })

编辑:由于您的vocabFile是Spark RDD,因此您将遇到vocabIndex的所有并行性问题。我建议改用@SteffenSchmitz的解决方案。

您需要能够将新值重新分配给vocabIndex,因此它应该是一个变量:

此外,Scala中的赋值结果是单位,而不是Java中的赋值。因此,您需要将代码分解为:

vocabFile.map(x => { val e = (vocabIndex, x); vocabIndex += 1; e })

编辑:由于您的vocabFile是Spark RDD,因此您将遇到vocabIndex的所有并行性问题。我推荐使用@SteffenSchmitz的解决方案。

您可以在RDD上使用.zipWithIndex函数

例如:

val input = List("Boat", "Car")
sc.parallelize(input).zipWithIndex().map(_.swap)
结果:

(0,Boat)
(1,Car)

我不建议使用共享变量作为索引,因为在整个集群中保持它的最新是很昂贵的。

您可以在RDD上使用.zipWithIndex函数

例如:

val input = List("Boat", "Car")
sc.parallelize(input).zipWithIndex().map(_.swap)
结果:

(0,Boat)
(1,Car)

我不建议使用共享变量作为索引,因为在整个集群中保持它的最新是昂贵的。

也许您可以在使用scala distinct后使用.zipWithIndex,以确保没有重复的元素:

例如:

val text = Seq(plane,car,car)
val result = text.distinct.zipWithIndex
res0: Seq[(String, Int)] = List((plane,0), (car,1)) 

也许您可以在使用scala distinct后使用.zipWithIndex,以确保没有重复的元素:

例如:

val text = Seq(plane,car,car)
val result = text.distinct.zipWithIndex
res0: Seq[(String, Int)] = List((plane,0), (car,1)) 

好的!我只需要以vocabFile.zipWithIndex.map\uz.swap的形式完成代码…这非常好用!但是否有从1开始索引的方法?我需要与另一个RDD进行连接,它的索引从1开始。如果不是的话,我可以总是在每个索引中添加一个,但如果能立即使用它,那就太好了。@alejandrogiron恐怕它总是以0开头,因为RDD和所有其他有序scala集合一样都是零索引的。那很好,我会进行映射,谢谢您的帮助!好的!我只需要以vocabFile.zipWithIndex.map\uz.swap的形式完成代码…这非常好用!但是否有从1开始索引的方法?我需要与另一个RDD进行连接,它的索引从1开始。如果不是的话,我可以总是在每个索引中添加一个,但如果能立即使用它,那就太好了。@alejandrogiron恐怕它总是以0开头,因为RDD和所有其他有序scala集合一样都是零索引的。那很好,我会进行映射,谢谢您的帮助!我因为某种原因得到了重复的值?数组[Int,String]=数组0,飞机,1,汽车,2,摩托车,0,卡车,1,船谢谢你的帮助!我因为某种原因得到了重复的值?数组[Int,String]=数组0,飞机,1,汽车,2,摩托车,0,卡车,1,船谢谢你的帮助!在分布式集群模式下,您的需求似乎不合适。由于RDD在本质上是分布式的,您的数据将被分区,这将不会为您提供文件中每个单词的实际索引,如果您不分区,那么该过程将不会有效。您的要求在分布式集群模式下似乎不合适。由于RDD在本质上是分布式的,您的数据将被分区,这将不会为您提供文件中每个单词的实际索引,如果您不分区,那么该过程将不会有效。