如何写一个条件收集在groovy?

想象一下,我有这样的结构:

class Foo { String bar } 

现在想象我有几个Foo的实例,它们的bar值是baz_1baz_2zab_3

我想写一个只收集包含文本bazbar值的collect语句。 我不能得到它的工作,但它看起来像这样:

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

你需要findAll

 barsOfAllFoos.findAll { it.contains 'baz' } 

如果你想过滤和转换有很多方法来做到这一点。 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 } 

使用findResults对我不起作用…如果你想收集符合条件的值的变换版本(例如对许多行的正则expression式search),你可以使用collect后面跟着findfindAll ,如下所示。

 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/'