web-dev-qa-db-fra.com

Comment écrire une collecte conditionnelle dans groovy?

Imaginez que j'ai cette structure:

class Foo {
   String bar
}

Maintenant, imaginez que j’ai plusieurs instances de Foo dont la valeur de bar est baz_1, baz_2, et zab_3.

Je veux écrire une instruction collect qui ne collecte que les valeurs bar qui contiennent le texte baz. Je ne peux pas le faire fonctionner, mais cela ressemblerait à ceci:

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' ]
62
ubiquibacon

Vous avez besoin de findAll :

barsOfAllFoos.findAll { it.contains 'baz' }
95
tim_yates

Si vous souhaitez à la fois filtrer et transformer, il existe de nombreuses façons de le faire. Après 1.8.1, j'irais avec #findResults et une fermeture qui renvoie null pour les éléments que je veux ignorer.

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

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

Dans les versions antérieures, vous pouvez utiliser #findAll et #collect

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

Ou #sum

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

Ou #inject

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

Utiliser findResults n'a pas fonctionné pour moi ... Si vous souhaitez collecter une version transformée des valeurs correspondant à la condition (par exemple, une recherche régulière sur plusieurs lignes), vous pouvez utiliser collect suivi de find ou findAll comme suit.

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}'"

Ceci retourne la partie de la ligne correspondant au motif donné.

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