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