我有多个if else和嵌套的if else语句。想知道有没有更好的方式来写这个?感谢你的指点。当前代码(if.else)在UDF中,将dataframe列作为输入来进行列值的条件检查(在该if else块中检查~5列)并返回true或false。
编辑:任何其他模式,如填充数据框中检查的条件,然后与数据框进行比较,其列在udf中检查,如Type,Flag 2,flag 3,flag,Fieldmdl等?
val retValue = 0
if (Type.startsWith("xyx "))
{
if (flag2 == 666)
{
if (flag3.toInt <= 100)
{
if (flag3 == 65)
{
retValue = 1
}
retValue = 0
}
else
{
if ((flag3 == "200" && flag5 == "10") || (flag3 == "198" && flag5== "10") )
{
if ((Fieldmdl.Contains("fff")) || (Fieldmdl.Contains("ggg")) || (Fieldmdl.Contains("hhh")) || (Fieldmdl.Contains("ttt yyy"))
)
{
retValue = 1
}
else {
retValue = 0
}
}
else
{
retValue = 1
}
}
}
}
if (Type.startsWith("waq"))
{
if (flag3.toInt < 123 )
{
retValue = 0
}
if (flag3 == "ggg" && (Fieldmdl == "aaa" || Fieldmdl == "bcc"))
{
retValue = 0
}
retValue = 1
}
}
<If (type.startswith("dddd"?>
{
check somethig and set the retvalue = 0 or 1
}
3条答案
按热度按时间35g0bw711#
你可以通过在Scala中使用模式匹配来简化嵌套的
if-else
语句:cygmwpex2#
除非你正在处理需要微优化的罕见用例(因为方法调用会导致几纳秒的速度减慢),否则使用描述性方法比多个嵌套的if-else更好。
yyhrrdl83#
如果逻辑真的很简单,你应该尽可能通过expr列函数使用dsl或sql。Spark的内置功能可以明显更快,因为udf需要转换参数和返回值,并且不能与整个stage代码生成内联。
在Spark方面,你可以继续使用if,但你也可以使用case / when并嵌套它们(在一定程度上取决于Spark版本,任何超过64 k的代码生成都可以抛出)。这些Spark原生条件也受益于不断折叠或优化器重写。
基于更新后的代码示例,我注意到Scala的三个要点:
1.更喜欢Sash Sinha提到的匹配
1.你应该遵循Luis的指导,使用if作为表达式,不要操纵状态,在那里一个简单的表达式结果将工作。
1.使用实际的布尔类型。
你可以用一点红外线来匹配
上面的StartsWith、Contains和IsInt不是必需的,但它使意图更清晰。
也就是说,你所拥有的大多数示例都非常适合Quality dq样式检查,你不会得到一个明确的if else,但你可以更容易地组织和审计所采取的路径,以及获得Spark内置优化。如果您真的需要“覆盖”结果,或者有多个udf,那么文件夹方法会很好地工作。
你可以根据sarveshseri的观点组织lambdas中的各种子if,以组合重用各种测试(即使你没有使用其他的Quality)。
只有当你计划经常改变这个if的规则,或者你确实添加了其他的if树udf时,这才真正有意义。