How to make Groovy / Grails return a List of objects instead of a List of Lists of objects?

假装没事ソ 提交于 2019-12-05 07:20:21

For generic groovy classes (i.e. non-GORM classes), David is correct that using flatten and unique is the best way to go.

In your example though, it looks like you're using GORM domain objects in a many-to-many relationship (otherwise you wouldn't need the uniqueness constraint).

For a domain class, you're best off using either HQL or a criteria to do this in one step. An additional advantage is that the SQL generated for it is much more efficient.

Here's the HQL for getting the unique Bar ids that are related to any Foo in a many-to-many relationship:

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

The criteria for this would look like:

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

One "issue" with using this kind of method is that HQL is not supported in unit tests (and likely will never be) and Criteria queries with join table projections are broken in 2.0.4 unit tests. So any tests around this code would either need to be mocked or use an integration test.

There is a Collection#collectMany method that works the same way as calling collect and then flatten. To get the list of Bar IDs, you might do:

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

The { it.bars*.id } closure returns a list with the IDs of the Bars of a Foo (i love these placeholder names hehe), and then collectMany concatenates those lists into a single list. If you need the IDs to be unique (maybe a Bar can belong to more than one Foo), you can add a .unique() to that expression :)

There might be a better way, but you could use flatten and unique.

Something like:

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

Edit:
I've just re-read and see that you are after a list of IDs in the end, not the Bars. As you suggested you would use collect{ it.id } to get the IDs. I would do that before making the list unique, for performance reasons.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!