如何在groovy中编写条件集合?

时间:2012-10-12 20:31:41

标签: groovy

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

class Foo {
   String bar
}

现在假设我有几个Foo bar值为baz_1baz_2zab_3的实例。

我想编写一个只收集包含文本bar的{​​{1}}值的collect语句。我无法让它工作,但它看起来像这样:

baz

3 个答案:

答案 0 :(得分:96)

您需要findAll

barsOfAllFoos.findAll { it.contains 'baz' }

答案 1 :(得分:44)

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

答案 2 :(得分:1)

使用findResults对我不起作用...如果要收集符合条件的值的转换版本(例如,对许多行进行正则表达式搜索),可以使用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/'