Scala 将下面的代码转换为函数范例

Scala 将下面的代码转换为函数范例,scala,Scala,我有一件很好用的。我只是想把它转换成功能性风格。问题是我将编写什么样的集合函数来将集合转换为值。这是spark streaming中使用的UpdateStateByKey函数的更新方法的签名 def updateFunction(newValues: Seq[(Int)], runningCount: Option[(Int)]): Option[(Int)] = { var result: Option[(Int)] = null if(newValues.isEmpty){

我有一件很好用的。我只是想把它转换成功能性风格。问题是我将编写什么样的集合函数来将集合转换为值。这是spark streaming中使用的UpdateStateByKey函数的更新方法的签名

def updateFunction(newValues: Seq[(Int)], runningCount: Option[(Int)]): Option[(Int)] = 
{
   var result: Option[(Int)] = null

   if(newValues.isEmpty){ 
         result=Some(runningCount.get)
      }
   else
   {
        newValues.foreach 
      { x => 
        {
             if(runningCount.isEmpty){
             result=Some(x)
        }
         else
        {
              result=Some(x+runningCount.get) 
        }
        } 
      }
   }
  result
}
它将被称为这个

val reducedRDD=keyValuelines.reduceByKey((x,y)=>(x+y))
val updatedRdd= reducedRDD.updateStateByKey(updateFunction)
如此有效

如果newValues为空,则获取runningCount。其他:

  • 如果runningCount为空-对新值求和
  • 如果存在运行计数-将新值和输出与运行计数相加
  • 我不想使用foreach,因为它不返回任何内容。所有其他收集函数似乎都不符合此标准

    我想把这段代码转换成函数代码。有人能确认这是正确的吗

    def updateFunctionVal(newValues: Seq[(Int)], runningCount: Option[(Int)]): Option[(Int)] = {
    
        val result = if (newValues.isEmpty) { //check if the key is present in new batch if not then return the old values
          Some(runningCount.get)
        }
        else {
          runningCount match {
            case x if runningCount.isEmpty => Some(newValues.fold(0)(_ + _))
            case _ => Some(newValues.fold(0)(_ + _) + runningCount.get)
          }
        }
        result
      }
    
    因此,为了明确函数的预期输出:如果
    newValues
    为空,只需返回
    runningCount
    。如果该值不为空,则返回最后一个值,并将
    runningCount
    中的值(如果存在)添加到该值中。对吗?如果
    newValues
    为空且
    runningCount
    None
    ,该怎么办?现在您抛出一个异常。在这种情况下,这里有一个返回
    None
    的版本:

    或者本质上相同,但更紧凑:

    编辑:您的第二次尝试具有完全不同的逻辑和输出。如果您能用简单的英语清楚地说明您希望函数做什么,这会有所帮助。

    因此,为了明确函数的预期输出:如果
    newValues
    为空,只需返回
    runningCount
    。如果该值不为空,则返回最后一个值,并将
    runningCount
    中的值(如果存在)添加到该值中。对吗?如果
    newValues
    为空且
    runningCount
    None
    ,该怎么办?现在您抛出一个异常。在这种情况下,这里有一个返回
    None
    的版本:

    或者本质上相同,但更紧凑:


    编辑:您的第二次尝试具有完全不同的逻辑和输出。如果您能用通俗易懂的英语阐明您希望函数做什么,这会有所帮助。

    假设我理解了您试图实现的逻辑:

    您有一个正在运行的计数,以及一个应全部添加到计数中的值列表。我相信您正在寻找的是
    foldLeft/Right
    操作:

    def update(newValues: Seq[(Int)], runningCount: Option[(Int)]) =
        newValues.foldLeft[Option[(Int)]](runningCount)((count, value) =>
            count match {
                case Some(initial) => Some(initial + value)
                case None => Some(value)
            })
    

    请注意,常规的
    折叠在这里不起作用,因为它只为扩展
    Int
    的类型定义(我认为这与关联规则有关,因为
    折叠
    不定义它是从左还是从右折叠)

    假设我理解了您试图实现的逻辑:

    您有一个正在运行的计数,以及一个应全部添加到计数中的值列表。我相信您正在寻找的是
    foldLeft/Right
    操作:

    def update(newValues: Seq[(Int)], runningCount: Option[(Int)]) =
        newValues.foldLeft[Option[(Int)]](runningCount)((count, value) =>
            count match {
                case Some(initial) => Some(initial + value)
                case None => Some(value)
            })
    

    请注意,常规的
    折叠在这里不起作用,因为它只为扩展
    Int
    的类型定义(我认为这与关联规则有关,因为
    折叠
    不定义它是从左还是从右折叠)

    鉴于文章中隐藏的描述,下面是一个使用
    reduceOption
    的实现:

    /*
    If the newValues is empty, get the runningCount. Else:
      If running count is present - sum the newValues and add runningCount
      else - sum the newValues
     */
    def updateFunction(newValues: Seq[(Int)], runningCount: Option[(Int)]): Option[Int] = {
      newValues
        .reduceOption(_ + _)                // sum of values, or None
        .map(_ + runningCount.getOrElse(0)) // add runningCount or 0 to sum
        .orElse(runningCount)               // if newValues was empty, just return runningCount
    }
    
    println(updateFunction(Seq(), Some(3)))     // Some(3)
    println(updateFunction(Seq(4, 5), Some(3))) // Some(12)
    println(updateFunction(Seq(4, 5), None))    // Some(9)
    println(updateFunction(Seq(), None))        // None
    

    鉴于文章中隐藏的描述,这里有一个使用
    reduceOption
    的实现:

    /*
    If the newValues is empty, get the runningCount. Else:
      If running count is present - sum the newValues and add runningCount
      else - sum the newValues
     */
    def updateFunction(newValues: Seq[(Int)], runningCount: Option[(Int)]): Option[Int] = {
      newValues
        .reduceOption(_ + _)                // sum of values, or None
        .map(_ + runningCount.getOrElse(0)) // add runningCount or 0 to sum
        .orElse(runningCount)               // if newValues was empty, just return runningCount
    }
    
    println(updateFunction(Seq(), Some(3)))     // Some(3)
    println(updateFunction(Seq(4, 5), Some(3))) // Some(12)
    println(updateFunction(Seq(4, 5), None))    // Some(9)
    println(updateFunction(Seq(), None))        // None
    

    这个函数做什么?看起来它返回给定的
    newValues
    中的最后一项加上
    runningCount
    的值(如果存在)。是这样吗?或者这意味着返回
    新值之和
    (它不返回)?无论如何,看看像
    fold
    foldLeft
    reduce
    等收集函数。
    runningCount
    作为
    选项[Int]
    ,而不是
    Int
    ,这个函数做什么?看起来它返回给定的
    newValues
    中的最后一项加上
    runningCount
    的值(如果存在)。是这样吗?或者这意味着返回
    新值之和
    (它没有)?无论如何,看看像
    fold
    foldLeft
    reduce
    等收集函数。
    runningCount
    作为
    选项[Int]
    而不是
    Int
    是否有令人信服的理由?是的,我完全同意。第二个是完全不同的逻辑。我对造成的混乱表示诚挚的歉意。如果newValues为空,则获取runningCount else 1。runningCount为空-对新值求和2。存在运行计数-将新值和输出与运行计数相加counts@Srinivas请编辑问题以包含此解释,并尽可能清楚地说明。例如-似乎您从未返回
    None
    (空
    选项
    )-是这样吗?如果是这样的话-为什么该方法会返回一个
    选项
    ?我已经提供了澄清,我为混淆道歉是的,我完全同意。第二个是完全不同的逻辑。我对造成的混乱表示诚挚的歉意。如果newValues为空,则获取runningCount else 1。runningCount为空-对新值求和2。存在运行计数-将新值和输出与运行计数相加counts@Srinivas请编辑问题以包含此解释,并尽可能清楚地说明。例如-似乎您从未返回
    None
    (空
    选项
    )-是这样吗?如果是这样的话-为什么该方法会返回一个
    选项
    ?我已经提供了说明,我为混淆道歉。我道歉,请再次查看我的编辑。我提供了澄清“…仅为扩展
    Int
    的类型定义”不正确<代码>折叠()
    适用于所有类型。元素类型和结果类型之间的关系比使用
    foldLeft
    /
    右键受到的限制更大