list.find (закрытие) и выполнение против этого значения - PullRequest
1 голос
/ 22 мая 2011

На самом деле мой вопрос: «Может ли приведенный ниже пример кода быть еще меньше? По сути, пример кода предназначен для того, чтобы сначала просмотреть список объектов, найти наиболее гранулированный (в данном случае это ветвь), а затем выполнить запрос назад в зависимости от какой объект он находит.

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

Но я считаю, что это вызовет исключение, поскольку эти объекты могут быть нулевыми

Ответы [ 3 ]

1 голос
/ 22 мая 2011

Я думаю, что @ virtualeyes почти имел его , но вместо сбора (который, как он говорит, вы не можете выйти из него), вы хотите использовать поиск, так как он останавливает выполнение первого действительного результат, который он получает:

List results = [Branch,Department,Organization].find { clazz->  
    Employees."findAllBy${clazz.name}"(listObjects?.find{it instanceof clazz})  
}
1 голос
/ 23 мая 2011

Вы можете сократить его немного больше с помощью findResult вместо цикла for in с переменной, которую необходимо определить снаружи:

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, ноон возвращает результат из первого ненулевого элемента, а не сам элемент.Это устраняет необходимость в отдельной переменной коллекции вне цикла.

Редактировать: то, что я ранее не вполне соответствовал поведению, которое, я думаю, вы искали (я не думаю, что другие ответы делаютлибо, но я могу быть недоразумением).Вы должны убедиться, что в списке есть что-то найденное, прежде чем выполнять 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

Я думаю, что этот кодна самом деле это более понятно, и это уменьшает количество итераций по списку и количество вызовов рефлексии, которые нам нужно сделать.

1 голос
/ 22 мая 2011

Редактировать
Цикл for in более эффективен, так как вы хотите прервать обработку первого ненулевого результата (т. Е. В 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; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...