Подтвердить что ты не робот

Как написать условный сбор в groovy?

Представьте, что у меня есть эта структура:

class Foo {
    String bar
}

Теперь представьте, что у меня есть несколько экземпляров Foo, значение bar которых baz_1, baz_2 и zab_3.

Я хочу написать инструкцию collect, которая собирает только теги bar, которые содержат текст baz. Я не могу заставить его работать, но он будет выглядеть примерно так:

def barsOfAllFoos= Foo.getAll().bar
assert barsOfAllFoos == [ 'baz_1', 'baz_2', 'zab_3' ]
def barsWithBaz = barsOfAllFoos.collect{ if( it.contains( "baz" ) { it } ) } // What is the correct syntax for this?
assert barsWithBaz == [ 'baz_1', 'baz_2' ]
4b9b3361

Ответ 1

Вам нужно findAll:

barsOfAllFoos.findAll { it.contains 'baz' }

Ответ 2

Если вы хотите как фильтровать, так и преобразовывать там много способов сделать это. После 1.8.1 я бы пошел с #findResults и замыканием, которое возвращает null для элементов, которые я хочу пропустить.

def frob(final it) { "frobbed $it" }

final barsWithBaz = barsOfAllFoos.findResults {
    it.contains('baz')? frob(it) : null
}

В более ранних версиях вы можете использовать #findAll и #collect

final barsWithBaz = barsOfAllFoos
                  . findAll { it.contains('baz') }
                  . collect { frob(it) }

Или #sum

final barsWithBaz = barsOfAllFoos.sum([]) {
    it.contains('baz')? [frob(it)] : []
}

Или #inject

final barsWithBaz = barsOfAllFoos.inject([]) {
    l, it -> it.contains('baz')? l << frob(it) : l
}

Ответ 3

Использование findResults не сработало для меня... Если вы хотите собрать преобразованную версию значений, соответствующих условию (например, поиск по регулярному выражению многих строк), вы можете использовать collect, за которым следует find или findAll следующим образом.

def html = """
    <p>this is some example data</p>
    <script type='text/javascript'>
        form.action = 'http://www.example.com/'
        // ...
    </script>
"""

println("Getting url from html...")
// Extract the url needed to upload the form
def url = html.split("\n").collect{line->
    def m = line =~/.*form\.action = '(.+)'.*/
    if (m.matches()) {
        println "Match found!"
        return m[0][1]
    }
}.find()

println "url = '${url}'"

Возвращает часть строки, соответствующую данному шаблону.

Getting url from html...
Match found!
url = 'http://www.example.com/'