真的我的问题是“下面的代码示例是否可以更小?基本上代码示例的目的是首先查看对象列表,找到最精细的(在这种情况下它是分支)然后根据查询向后查询它找到了什么对象。
1 - 如果找到分支,则将findAllBy返回分支
2 - 如果找到某个部门,则将findAllBy返回部门
3 - 如果找到组织,则将findAllBy返回给组织
目标是找到最精细的对象(这就是为什么顺序很重要),但是我需要有两个单独的块(一个用于定义对象,另一个用于检查它们是否存在)?或者可以将这两个命令组合成一个命令......
def resp
def srt = [sort:"name", order:"asc"]
def branch = listObjects.find{it instanceof Branch}
def department = listObjects.find{it instanceof Department}
def organization = listObjects.find{it instanceof Organization}
resp = !resp && branch ? Employees.findAllByBranch(branch,srt) : resp
resp = !resp && department ? Employees.findAllByDepartment(department,srt) : resp
resp = !resp && organization ? Employees.findAllByOrganization(organization,srt) : resp
return resp
我在想的是这样的:
def resp
resp = Employees.findAllByBranch(listObjects.find{it instanceof Branch})
resp = !resp ? Employees.findAllByDepartment(listObjects.find{it instanceof Department}) : resp
resp = !resp ? Employees.findAllByOrganization(listObjects.find{it instanceof Organization}) : resp
但我相信会抛出异常,因为这些对象可能为null
答案 0 :(得分:1)
修改强>:
for循环更有效,因为你想要破坏第一个非null结果的处理(即在Groovy中我们不能用“return”或“break”中断闭包迭代)。
def resp
for(clazz in [Branch,Department,Organization]) {
resp = Employees."findAllBy${clazz.name}"(listObjects?.find{it instanceof $clazz})
if(resp) return
}
if(resp) // do something...
<强>原始强>:
List results = [Branch,Department,Organization].collect{clazz->
Employees."findAllBy${clazz.name}"(listObjects?.find{it instanceof $clazz})
}
享受Groovy; - )
答案 1 :(得分:1)
我认为@virtualeyes nearly had it,而不是收集(正如他所说,你不能突破),你想使用一个find,因为它停止运行它得到的第一个有效结果:
List results = [Branch,Department,Organization].find { clazz->
Employees."findAllBy${clazz.name}"(listObjects?.find{it instanceof clazz})
}
答案 2 :(得分:1)
您可以使用findResult
将其缩短一点,而不是使用需要在外部进行def的变量的for循环:
def listObjects // = some predetermined list that you've apparently created
def srt = [sort:"name", order:"asc"]
def result = [Branch, Department, Organization].findResult { clazz ->
listObjects?.find { it.class.isAssignableFrom(clazz) }?.with { foundObj ->
Employees."findAllBy${clazz.name}"(foundObj, srt)
}
}
findResult
与find
类似,但它返回第一个非null项而不是项本身的结果。它避免了在循环之外需要单独的集合变量。
编辑:我之前所做的与我认为你正在寻找的行为并不完全相符(我不认为其他答案也是如此,但我可能会误解)。你必须确保在执行findAllBy之前在列表中找到了一些东西,否则你可能会撤回不是你正在寻找的空项目。
在实际的生产代码中,我实际上做的事情有点不同。我利用JVM类型系统只需要在找到第一个分支/部门/组织时,一次又一次地绕过listObjects
短路:
def listObjects
def sort = [sort:"name", order:"asc"]
def result = listObjects?.findResult { findEmployeesFor(it, sort) }
... // then have these methods to actually exercise the type specific findEmployeesFor
def findEmployeesFor(Branch branch, sort) { Employees.findAllByBranch(branch, sort) }
def findEmployeesFor(Department department, sort { Employees.findAllByDepartment(department, sort)}
def findEmployeesFor(Organization organization, sort { Employees.findAllByOrganization(organization, sort)}
def findEmployeesFor(Object obj, sort) { return null } // if listObjects can hold non/branch/department/organization objects
我认为这段代码实际上更清晰,它减少了我们遍历列表的次数以及我们需要进行的反射调用次数。