Groovy - как выйти из каждого цикла?

Я новичок в Grails/ Groovy и пытаюсь найти node в XML файле; Я выяснил, как перебирать все из них, но я хочу выйти из цикла, когда найден объект node. Я читал, что вместо того, чтобы использовать "каждый", используйте "find", но примеры поиска, которые я видел, - это условия. Прямо сейчас логика, которую я имею, будет проходить через весь файл без выхода. Код ниже:

  records.children().each {domain ->
   println "domain_name: " + [email protected]_name
   if ([email protected]_name == targetDomain) {

    println "target domain matched: " + [email protected]_name

    domain.children().each {misc_field ->

     println "field_name: " + [email protected]_name
     println "field_type: " + [email protected]_type
     println "field_value: " + misc_field

    }



   }
  }

Ответ 1

Вы не можете сделать это элегантно. Вы могли бы увидеть, что некоторые люди предлагают бросить исключение, но это просто уродливый.

Здесь несколько обсуждение списка рассылки при использовании each vs. for, а пара людей говорят, что for является предпочтительным из-за each невозможности выхода из итерации.

Лучше всего переходить на цикл for и повторять:

for(def domain : records.children()) { // this may need some tweaking depending on types
    // do stuff
    if(condition) {
        break;
    }
}

Либо это, либо как вы сказали, возможно, используйте find или findAll, чтобы найти элемент, который вы ищете (следующий код перефразирован, у меня еще нет времени проверить его):

def result = records.children().find { domain -> [email protected]_name == targetDomain }
result.children().each {
    // print stuff
}

Связанные вопросы SO:

Ответ 2

Относительно выхода из каждого цикла см. возможно ли "вырваться" из закрытия groovy

В принципе, вам нужно бросить и исключить и поймать его. Ключевое слово "break" разрешено только внутри циклов, а не повторенных "закрытий" (на самом деле блоков кода).

Вы можете использовать любой сложный код с "find", просто убедитесь, что вызываемая вами функция возвращает логическое значение. Например:

Boolean test(val) {
    println "Testing $val"
    return val == 1
}

def found = [3,4,5,1,6,3].find { test(it) }

println "Found $found"

Ответ 3

Я думаю, что это тоже должно работать, останавливаясь в первом матче.

def result = records.children().find { domain -> 
    if ([email protected]_name == targetDomain) {
        // Do stuff
        ...
        return true
    } else {
        return false
    }
}

Ответ 4

Замените цикл each на любое или нахождение.

def list = [1, 2, 3, 4, 5]
list.any { element ->
    if (element == 2)
        return // continue

    println element

    if (element == 3)
        true // break
}

Выход

1
3