2015-11-27 7 views
3

Я знаю, мы не можем вернуться с .each{} Закрытие в groovy, как .find{} Закрытие. Тем не менее мне любопытно, почему приведенный ниже код выполняет только первую итерацию .find{}.Вложенность groovy each {} внутри find {}

def findlist = [1,2,3,4,5] 
def eachlist = [7,6,5] 

findlist.find 
{ 
    int findelem = it 
    println "findelem : " + findelem 
    eachlist.each 
    { 
     int eachelem = it 
     println "eachelem : " + eachelem 
     if(it == findelem) 
     { 
      return true 
     } 
     return false 
    } 
} 

Он печатает:

findelem : 1 
eachelem : 7 
eachelem : 6 
eachelem : 5 

find{} Почему выходит после первой итерации?

PS: Я понимаю, что этот код может не иметь никакого практического значения, просто любопытно о хорошем поведении.

ответ

3

Потому что each возвращает немодифицированный коллекция итераций. Возвращенная коллекция оценивается в true, поэтому find останавливается после первой итерации.

Посмотрите на код ниже:

assert [1, 2].each { println it } == [1,2] 

assert [1,2].find { println it; [3, 4].each { e -> println e } } 

Вам нужно гнездо find вместо each.

+0

так 'каждый {}' всегда возвращает всю коллекцию его итерация на? – Mahesha999

+0

Да, так оно и работает. Пожалуйста, посмотрите [источники] (https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java#L1889). – Opal

2

Просто, чтобы закончить ответ опала (каждый возвращает коллекцию, так что будет истинным, если оно не пусто), вы можете использовать локальную переменную внутри find закрытия, чтобы вернуть найденное значение. Упрощая код немного:

assert 5 == findlist.find { findelem -> 
    println "findelem : " + findelem 
    boolean found 
    eachlist.each { eachelem -> 
     println "eachelem : " + eachelem 
     found = (eachelem == findelem) 
    } 
    found 
} 

Однако, есть лучше и groovier путь:

assert 5 == findlist.find { it in eachlist } 
Смежные вопросы