【问题标题】:How to make Groovy / Grails return a List of objects instead of a List of Lists of objects?如何让 Groovy / Grails 返回对象列表而不是对象列表列表?
【发布时间】:2012-06-23 04:41:04
【问题描述】:

我有这样的课:

class Foo {
    static hasMany = [bars: Bar]
}

当我写作时:

Foo.getAll()

我得到一个 Foo 对象列表,如下所示:

[ Foo1, Foo2, Foo3 ]

当我写作时:

Foo.getAll().bars

我得到一个 Bar 对象列表列表,如下所示:

[ [ Bar1, Bar2 ], [ Bar2, Bar3 ], [ Bar1, Bar4 ] ] 

但我想要的是 Bar 对象的唯一列表,如下所示:

[ Bar1, Bar2, Bar3, Bar4 ]

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

[ 1, 2, 3, 4 ]

我尝试过collect 方法的变体,也尝试过spread operator,但我没有任何运气。

【问题讨论】:

    标签: grails collections groovy closures collect


    【解决方案1】:

    可能有更好的方法,但您可以使用flattenunique

    类似:

    def allBars = Foo.getAll().bars.flatten().unique()

    编辑:
    我刚刚重新阅读并看到您最终是在寻找一个 ID 列表,而不是 Bars。正如您所建议的,您将使用 collect{ it.id } 来获取 ID。出于性能原因,我会在使列表独一无二之前这样做。

    【讨论】:

      【解决方案2】:

      有一个Collection#collectMany 方法与调用collect 然后flatten 的工作方式相同。要获取 Bar ID 列表,您可以这样做:

      def barIds = Foo.getAll().collectMany { it.bars*.id }
      

      { it.bars*.id } 闭包返回一个带有 Foo 的 Bars 的 ID 的列表(我喜欢这些占位符名称,呵呵),然后 collectMany 将这些列表连接成一个列表。如果您需要唯一的 ID(也许 Bar 可以属于多个 Foo),您可以在该表达式中添加 .unique() :)

      【讨论】:

        【解决方案3】:

        对于通用的 groovy 类(即非 GORM 类),David 是正确的,使用 flattenunique 是最好的方法。

        不过,在您的示例中,您似乎在多对多关系中使用 GORM 域对象(否则您将不需要唯一性约束)。

        对于域类,您最好使用 HQL 或标准一步完成。另一个优点是为其生成的 SQL 效率更高。

        这是获取与任何 Foo 以多对多关系相关的唯一 Bar id 的 HQL:

        Bar.executeQuery("select distinct b.id from Foo f join f.bars b")
        

        标准如下:

        Foo.withCriteria {
            bars {
                projections {
                  distinct("id")
                }
            }
        }
        

        使用这种方法的一个“问题”是单元测试不支持 HQL(可能永远不会支持)和Criteria queries with join table projections are broken in 2.0.4 unit tests。因此,围绕此代码的任何测试都需要模拟或使用集成测试。

        【讨论】:

        • 感谢您的所有回答。希望我能给你们更多的支持 :) 我想避免 HQL,但是使用标准几乎完成了我的任务,我现在发现分页是……麻烦。如果我无法使用标准让分页效果很好,我认为我将不得不去 HQL。
        猜你喜欢
        • 2020-07-17
        • 1970-01-01
        • 2018-12-18
        • 1970-01-01
        • 2021-07-05
        • 1970-01-01
        • 2021-07-21
        • 1970-01-01
        • 2021-09-18
        相关资源
        最近更新 更多