我想知道如何改进此代码以使其更具可读性和流畅性。感谢您的帮助,谢谢。
// filter DWT based on Zone
val dwtListZon = query.zoneOpt match {
case None => dwtListStn
case Some(zon) => {
if (zon.crwStn333 == "all") {
dwtListStn
}
dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3)
}
}
我只想了解这个代码应该如何在简单性和可读性方面以更具说明性(如果可能)的方式编写。
下面的答案显示了做同样事情的不同风格,这也有助于扩大我对FP和Scala的总体洞察力。谢谢你!
答案 0 :(得分:5)
您可能还会考虑fold
上提供的Option
功能。对于具有默认值的Options
来说,它通常是一个很好的语法,你可以使用优雅的部分函数语法:
query.zoneOpt.fold(dwtListStn) {
case zon if zon.crwStn333 == "all" => dwtListStn
case zon => dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3)
}
这里的另一个一般策略是翻转操作。所有逻辑分支都返回dwtListStn
的过滤或未过滤版本,因此您可以将整个操作视为filter
:
dwtListStn.filter { dwt =>
query.zoneOpt match {
case Some(zone) if zone.crwStn333 == "all" => false
case Some(zone) => dwt.crwStnAbbr3 == zon.crwStnAbbr3
case None => false
}
}
答案 1 :(得分:2)
val dwtListZon = query.zoneOpt filter (_.crwStn333 != "all") map (zon =>
dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3) ) getOrElse dwtListStn
或者如果你想要可读性
val filteredSomething = for(zon <- query.zoneOpt if zon.crwStn333 != "all")
yield dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3)
val dwtListZon = filteredSomething getOrElse dwtListStn
答案 2 :(得分:1)
正常匹配也很清楚。如果条件只是反转:
query.zoneOpt match {
case Some(zon) if (zon.crwStn333 != "all") =>
dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3)
case _ =>
dwtListStn
}