避免在 If Else 中重复调用 Scala 中的同一函数
我有以下我想优化的代码片段:
import org.joda.time.{DateTime, Days, Months, Weeks, Years}
@scala.annotation.tailrec
def optimize(start: DateTime, end: DateTime, acc: List[(DateTime, DateTime)]): List[(DateTime, DateTime)] = {
def doDaysExist(startDate: DateTime, endDate: DateTime): Boolean = {
Days.daysBetween(startDate, endDate).getDays != 0
}
if (Years.yearsBetween(start, end.plusDays(1)).getYears != 0) {
val years = Years.yearsBetween(start, end.plusDays(1)).getYears
val newStart = start.plusYears(years).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else if (Months.monthsBetween(start, end.plusDays(1)).getMonths != 0) {
val months = Months.monthsBetween(start, end.plusDays(1)).getMonths
val newStart = start.plusMonths(months).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else if (Weeks.weeksBetween(start, end.plusDays(1)).getWeeks != 0) {
val weeks = Weeks.weeksBetween(start, end.plusDays(1)).getWeeks
val newStart = start.plusWeeks(weeks).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else {
// For sure days
(start, end) +: acc
}
}
可以看出,if 条件和后面的下一个语句是重复的代码。有没有更好的方法让它变得更好、更神秘?我必须逐步遍历这个层次结构,因为我必须首先检查年份,然后是月份,然后是星期,然后是日期。
我可以考虑将重复的代码块提取到 lambda 中,但这足够好吗?我无法考虑将其重写为 Map,因为该代码块在尾递归函数中运行。
I have the following code snippet that I would like to optimize:
import org.joda.time.{DateTime, Days, Months, Weeks, Years}
@scala.annotation.tailrec
def optimize(start: DateTime, end: DateTime, acc: List[(DateTime, DateTime)]): List[(DateTime, DateTime)] = {
def doDaysExist(startDate: DateTime, endDate: DateTime): Boolean = {
Days.daysBetween(startDate, endDate).getDays != 0
}
if (Years.yearsBetween(start, end.plusDays(1)).getYears != 0) {
val years = Years.yearsBetween(start, end.plusDays(1)).getYears
val newStart = start.plusYears(years).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else if (Months.monthsBetween(start, end.plusDays(1)).getMonths != 0) {
val months = Months.monthsBetween(start, end.plusDays(1)).getMonths
val newStart = start.plusMonths(months).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else if (Weeks.weeksBetween(start, end.plusDays(1)).getWeeks != 0) {
val weeks = Weeks.weeksBetween(start, end.plusDays(1)).getWeeks
val newStart = start.plusWeeks(weeks).minusDays(1)
if (doDaysExist(newStart, end)) {
optimize(newStart, end, (start, newStart) +: acc)
} else (start, end) +: acc
} else {
// For sure days
(start, end) +: acc
}
}
As it can be seen that the if condition and the next statement that follows are kind of duplicate code. Is there a better way to make it better and cryptic? I have to step through this hierarchy as I have to first check the year, then the month, then the week and then the day.
I can think of extracting the repeated code block into lambdas, but is that good enough? I can't think of rewriting it as a Map as that code block runs in a tail recursive function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
像这样的事情怎么样:
What about something like this:
只需预先计算值并将第二个测试移到 if/else 之外:
使用
lazy
可能会也可能不会提高性能,因此请衡量以查看哪个是最好的。Just pre-compute the values and move the second test outside the if/else:
Using
lazy
may or may not improve performance so measure to see which is best.