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' ]
Vous avez besoin de findAll
:
barsOfAllFoos.findAll { it.contains 'baz' }
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
}
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/'