【问题标题】:illegal start of declaration error with foreachforeach 声明错误的非法开始
【发布时间】:2020-01-31 06:26:58
【问题描述】:

我想为每个 score_threshold 显示 Column1 的不同计数;但是,我收到此行的“非法声明开始”错误:

results = results :+ (threshold,count)

我正在尝试 z.show() 这些计数在 Zeppelin 笔记本中的图表上。

我有以下 scala 代码:

val score_threshold = Seq(50.0,100.0,200.0,250.00,500.00,1000.00) 
var results = Seq((0.0,0.0)) 

    score_threshold.foreach(threshold:Double => {
        val counts = DF.filter($"score" >= threshold)
            .groupBy().agg(countDistinct("column1").as("count")).rdd.map(x=> x.getDouble(0)).collect.head
        results = results :+ (threshold,count)
        })
z.show(results.toDF("threshold","count")) 

这是我得到的错误:

error: illegal start of declaration
        results = results :+ (threshold,count)

【问题讨论】:

  • score_threshold 是字符串序列,而不是双精度序列。您必须将其读取为字符串并将每个值转换为双精度。

标签: scala foreach apache-zeppelin


【解决方案1】:

首先,val counts 是否应该是val count

当您在 foreach 调用中使用 () 时,您只能传递一个简单的表达式作为参数。要使您的论点成为一个简单的表达式,您必须在 () 中加上 threshold:Double。

score_threshold.foreach( (threshold: Double) => {
  val counts = DF.filter($"score" >= threshold)
  .groupBy().agg(countDistinct("column1").as("count")).rdd.map(x=> x.getDouble(0)).collect.head
  results = results :+ (threshold,count)
}

如果我可以推荐一个(恕我直言)更好的变体。当你知道你要传递的函数不是一个简单的表达式时,你应该在foreach之后使用{}

score_threshold.foreach { threshold: Double =>
  val counts = DF.filter($"score" >= threshold) .groupBy().agg(countDistinct("column1").as("count")).rdd.map(x=> x.getDouble(0)).collect.head
  results = results :+ (threshold,count)
}

只是为了烦人(并且没有任何关于 apache-zeppelin 的知识),我添加了一个功能更强大的替代方案,使用 foldLeft 而不是使用 var

score_threshold.foldLeft(Seq((0.0,0.0))) {
  case (acc, next) =>
    val count = DF.filter($"score" >= next) .groupBy().agg(countDistinct("column1").as("count")).rdd.map(x=> x.getDouble(0)).collect.head
    acc :+ (next,count)
}

【讨论】:

  • 谢谢!我使用了你的第二个版本:val score_threshold = Seq(50.0,100.0,200.0,250.00,500.00,1000.00) var results = Seq[(Double,Long)]() score_threshold.foreach { threshold: Double => val count = DF .filter($"score" >= threshold) .groupBy().agg(countDistinct("column1").as("count")).rdd.map(x=> x.getLong(0)).collect.head results = results :+ (threshold,count) } z.show(results.toDF("score_threshold","count"))
【解决方案2】:
I was able to resolve the issue, but your solution is faster. 

val score_threshold = Seq(50.0,100.0,200.0,250.00,500.00,1000.00) 
var results = Seq[(Double,Double)]() 

score_threshold.foreach(threshold => { 
val count = Df.filter($"score" >= threshold).groupBy().agg(countDistinct("column1").as("count").cast(DoubleType)).rdd.map(x=> x.getDouble(0)).collect.head 

results = results :+ (threshold,count) }) 
z.show(results.toDF("score_threshold","count"))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-17
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多