我有以下函数,它根据某些条件返回一个标志。
试着看看是否有更好的Scala方法来实现同样的目标?
基于人的状态,基本上有不同的规则可以在pass_ind标志上派生。
如果人员身份是学生或失业,则有一些收入规则,如果此人身份不在学生或失业状态,则有不同的规则适用于分数和&收入
def IncomeScreenStatus(status_cd: Option[String],
score: Option[Int],
income: Option[Double]) : String = {
var pass_ind : String = "F"
if (score.isDefined && income.isDefined && status_cd.isDefined) {
val score : Int = score.get
val income : Double = income.get
val status_cd : String = status_cd.get
if (status_cd == "STUDENT" || status_cd == "UNEMPLOYMENT") {
pass_ind = (status_cd, income) match {
case ("UNEMPLOYMENT", income) if income <= 7000 => "P"
case ("STUDENT", income) if income <= 18000 => "P"
case _ => "F"
}
}
else {
pass_ind = (income, score) match {
case (income, score) if (score < 100 || score > 150) && income <= 8500 => "P"
case (income, score) if (score <= 167 && score >= 100) && income <= 10500 => "P"
case _ => "F"
}
}
}
pass_ind
}
答案 0 :(得分:1)
也许是这样的? (我没有尝试过,没有保证它是正确的。)
def IncomeScreenStatus( mb_status_cd : Option[String], mb_score : Option[Int], mb_income : Option[Double]) : String = {
def nsu( score : Int, income : Double ) = { // neither student nor unemployed
if ( (score < 100 || score > 150) && income <= 8500 ) "P"
else if ( (score <= 167 && score >= 100) && income <= 10500 ) "P"
else "F"
}
( mb_status_cd, mb_score, mb_income ) match {
case ( Some( "STUDENT" ), Some( score ), Some( income ) ) if ( income <= 18000 ) => "P"
case ( Some( "UNEMPLOYMENT" ), Some( score ), Some( income ) ) if ( income <= 7000 ) => "P"
case ( Some( "STUDENT" | "UNEMPLOYMENT" ), Some( _ ), Some( _ ) ) => "F"
case ( Some( _ ), Some( score ), Some( income ) ) => nsu( score, income )
case _ => "F"
}
}
答案 1 :(得分:1)
这是第一次破解。
def IncomeScreenStatus(status_cd: Option[String]
,score : Option[Int]
,income : Option[Double]) : String = {
for {
stat <- status_cd
scr <- score
incm <- income
} yield stat match {
case "UNEMPLOYMENT" => if (incm <= 7000) "P" else "F"
case "STUDENT" => if (incm <= 18000) "P" else "F"
case _ => if ((scr < 100 || scr > 150) && incm <= 8500 ||
(scr <= 167 && scr >= 100) && incm <= 10500) "P" else "F"
}
}.getOrElse("F")
创建与传入参数同名的局部变量确实会使编译器感到困惑。
答案 2 :(得分:1)
首先,我对Scala采用的推荐代码风格的评论很少,
camelCase
incomeScreenStatus
代替IncomeScreenStatus
。statusCd
代替status_cd
passInd
代替pass_ind
现在,
def incomeScreenStatus(statusCd: Option[String],
score: Option[Int],
income: Option[Double]) : String = {
(score, income, statusCd) match {
case (Some(scoreV), Some(incomeV), Some(statusCdV)) => {
(statusCdV, incomeV, scoreV) match {
case ("UNEMPLOYMENT", _, _) if incomeV <= 7000 => "p"
case ("STUDENT", _, _) if incomeV <= 18000 => "p"
case _ if (scoreV < 100 || scoreV > 150) && incomeV <= 8500 => "P"
case _ if (scoreV <= 167 && scoreV >= 100) && incomeV <= 10500 => "P"
case _ => "F"
}
}
case _ => "F"
}
}
答案 3 :(得分:0)
在函数式编程中,最好使用小函数而不是大函数。我更喜欢做以下事情:
def screenStudent(income:Double):String = {
if (income <= 18000) "P" else "F"
}
def screenUnemployment(income:Double):String = {
if (income <= 7000) "P" else "F"
}
def screenOthers(income:Double, score:Int):String = {
(income, score) match {
case (income, score) if (score < 100 || score > 150) && income <= 8500 => "P"
case (income, score) if (score <= 167 && score >= 100) && income <= 10500 => "P"
case _ => "F"
}
}
def incomeScreenStatus(
status_cd: Option[String],
score: Option[Int],
income: Option[Double]
) : String =
(status_cd , score, income) match {
case (Some("STUDENT"), Some(_), Some(i)) => screenStudent(i)
case (Some("UNEMPLOYMENT"), Some(_), Some(i)) => screenUnemployment(i)
case (Some(_), Some(s), Some(i)) => screenOthers(i, s)
case _ => "F"
}
答案 4 :(得分:0)
由于您的示例需要定义每个字段,因此您可以将Task task;
using(var something = GetSomething()){
task = something.TaskThatWillFailAndExplodeIfExecutedWhenSomethingIsDisplosed();
}
task.Wait(); // BOOM
压缩在一起。我也想在我的案例陈述中使用提取器代替显式保护。
如果您的状态是有限集合,我还建议使用Option
来表示它。
sealed trait