如何使Groovy/Grails返回一个对象列表而不是一个对象列表?

ubi*_*con 6 collections grails groovy closures collect

我有一个这样的课:

class Foo {
    static hasMany = [bars: Bar]
}
Run Code Online (Sandbox Code Playgroud)

我写的时候:

Foo.getAll()
Run Code Online (Sandbox Code Playgroud)

我得到一个Foo像这样的对象列表:

[ Foo1, Foo2, Foo3 ]
Run Code Online (Sandbox Code Playgroud)

我写的时候:

Foo.getAll().bars
Run Code Online (Sandbox Code Playgroud)

我得到一个Bar像这样的对象列表:

[ [ Bar1, Bar2 ], [ Bar2, Bar3 ], [ Bar1, Bar4 ] ] 
Run Code Online (Sandbox Code Playgroud)

但我想要的是一个Bar像这样的唯一对象列表:

[ Bar1, Bar2, Bar3, Bar4 ]
Run Code Online (Sandbox Code Playgroud)

我的最终目标是Bar在上面的列表中有一个唯一的对象ID 列表,如下所示:

[ 1, 2, 3, 4 ]
Run Code Online (Sandbox Code Playgroud)

我尝试过收集方法的各种变化,我也尝试过传播算子,但我没有运气.

Ted*_*eid 8

对于通用的groovy类(即非GORM类),David是正确的,使用flatten并且unique是最好的方法.

在您的示例中,看起来您在多对多关系中使用GORM域对象(否则您将不需要唯一性约束).

对于域类,您最好使用HQL或条件一步完成此操作.另一个优点是为它生成的SQL效率更高.

以下是用于获取BarFoo多对多关系中的任何内容相关的唯一ID 的HQL :

Bar.executeQuery("select distinct b.id from Foo f join f.bars b")
Run Code Online (Sandbox Code Playgroud)

这个标准看起来像:

Foo.withCriteria {
    bars {
        projections {
          distinct("id")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法的一个"问题"是单元测试中不支持HQL(可能永远不会),并且在2.0.4单元测试中会破坏具有连接表投影的Criteria查询.因此,围绕此代码的任何测试都需要进行模拟或使用集成测试.