Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala似乎忽略了一些代码_Scala_Apache Spark - Fatal编程技术网

Scala似乎忽略了一些代码

Scala似乎忽略了一些代码,scala,apache-spark,Scala,Apache Spark,这对我来说很奇怪。我熟悉Scala中map和foreach之间的区别以及两者的用例,但可能我不了解其他方面。我第一次遇到这个问题是在我玩Spark的时候,所以这可能只是在我使用RDD的时候才表现出来的 下面的代码似乎忽略了对map的调用。 我正在使用Scala 2.11.1,下面是我运行以下代码的依赖项 libraryDependencies ++= Seq( "org.apache.spark" %% "spark-core" % "2.1.0", "org.apache.spark"

这对我来说很奇怪。我熟悉Scala中
map
foreach
之间的区别以及两者的用例,但可能我不了解其他方面。我第一次遇到这个问题是在我玩Spark的时候,所以这可能只是在我使用RDD的时候才表现出来的

下面的代码似乎忽略了对map的调用。 我正在使用Scala 2.11.1,下面是我运行以下代码的依赖项

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "2.1.0",
  "org.apache.spark" %% "spark-sql" % "2.1.0"
)
下面的内容可以粘贴到scala控制台中

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.rdd.RDD
import org.apache.spark.RangePartitioner

val conf: SparkConf = new SparkConf().setMaster("local").setAppName("Test")
val sc: SparkContext = new SparkContext(conf)


val rdd: RDD[Tuple2[String, String]] = sc.parallelize(List(
  ("I", "India"),
  ("U", "USA"),
  ("W", "West")))

val rp = new RangePartitioner(3, rdd)
val parts = rdd.partitionBy(rp).cache()

parts.mapPartitionsWithIndex( (x,y) => { y.map(println); y } ).collect()
运行此命令时,您可以看到没有任何内容打印到标准输出。但是,如果将最后一行代码更改为
parts.mapPartitionsWithIndex((x,y)=>{y.map(println)}).collect()
甚至是这个
parts.mapPartitionsWithIndex((x,y)=>{y.foreach(println);y}).collect()
它将被打印出来


我相信这与关于stdout未被输出的问题不同,因为我处于本地模式,这是RDD not stdout的评估问题。

传递到
mapPartitionsWithIndex
的函数类型是
(Int,迭代器[T])⇒ 迭代器[U]
因此在您的示例中,
y
是一个
迭代器

在Scala中,迭代器是一个惰性集合,换句话说,在需要结果之前它不会做任何工作(类似于RDD)

在代码
(x,y)=>{y.map(println);y}
中,map转换返回一个新的
迭代器
,其中每个元素在计算时都将被打印出来并替换为
单位
。然后放弃该迭代器并返回原始迭代器,使输出
RDD
与输入相同。由于从不使用map生成的迭代器,因此不会对函数求值,也不会打印任何内容

在“工作”代码中,
(x,y)=>{y.map(println)}
应用相同的映射转换,但返回它生成的迭代器。因此,当您计算从转换创建的
RDD
时(使用
collect
),将打印行(还请注意,生成的
RDD
将包含所有
单位值)


在另一个示例中,
(x,y)=>{y.foreach(println);y}
您使用
foreach
,它严格计算迭代器的每个元素,并返回单位。然后返回输入迭代器(现在为空,因为您已经使用了所有元素)。当使用
collect
计算
RDD
时,运行此块并打印元素,请注意结果
RDD
是如何为空的。

在什么情况下它不会被打印?在导入的完整代码示例中,没有任何内容被打印到标准输出。如果您能够在标准输出中看到每个示例的某些内容,则可能是安装问题。您是否在本地运行此功能?plz指定了不使用确切的代码差异运行的情况。
RDD
的可能副本是惰性数据结构。因此,除非您从
RDD
中“消费”,否则不会进行实际计算。这里,您对
collect()
的消费迫使
RDD
进行真正的自我评估。很抱歉,但简单地说,因为第一种情况不包含
动作,第二种情况包含???@cue动作是一个特定于火花的术语,我们在这里讨论的是
迭代器,所以是简单的scala。但基本上是相同的想法<迭代器上的code>map
不会立即执行任何操作,而是返回一个新的迭代器,其中每个元素在求值时都会将函数传递到map中。如果您从未对返回的迭代器执行任何操作,
map
中的代码将永远不会运行。感谢您的解释!我在某种程度上理解spark的惰性评估,但没有意识到它也适用于儿童RDD,这是有意义的。大多数情况下,我并不认为分区也会返回RDDs。。。当然,在阅读了你的答案之后,这也有道理。@mschuett我需要重申,这个特定的问题与spark或RDDs无关,迭代器是一个标准的Scala类,它也有类似的惰性语义