This sounds like a great addition!
Naming is consistent with our existing methods.

Guillaume


*Guillaume Laforge*
Apache Groovy committer
Developer Advocate @ Google Cloud <https://cloud.google.com/>

   - Blog: glaforge.dev
   - X: @glaforge <http://twitter.com/glaforge>
   - Bluesky: @glaforge.dev <https://bsky.app/profile/glaforge.dev>
   - Mastodon: @[email protected] <http://%[email protected]/>


Le mer. 26 nov. 2025, 08:23, Paul King <[email protected]> a écrit :

> Hi folks,
>
> I was recently looking at some of the functionality offered by Eclipse
> Collections. One nice feature is its groupByEach method. It simplifies
> using collectMany then groupBy.
>
> To fit in with Groovy naming, I think groupByMany is slightly better
> in Groovy's case but the examples below show how current functionality
> works (using collectMany/groupBy and then using groovy-ginq) and then
> how be done using groupByMany:
>
> def citiesLived = [
>     Alice: ['NY', 'LA'],
>     Bob: ['NY'],
>     Cara: ['LA', 'CHI']
> ]
>
> We want the reverse map of cities -> list of names:
>
> def grouped1 = citiesLived
>     .collectMany(e -> e.value.collect{ c -> [c, e.key] })
>     .groupBy{ c, n -> c }
>     .collectEntries{ key, value -> [key, value*.get(1)] }
> check(grouped1)
>
> Alternatively, we can use groovy-ginq:
>
> def grouped2 = GQL {
>     from n in citiesLived.keySet()
>     crossjoin c in citiesLived.values().sum().toSet()
>     where c in citiesLived[n]
>     groupby c
>     select c, list(n)
> }
> check(grouped2.collectEntries())
>
> Here is what it looks like with the proposed method:
>
> def grouped3 = citiesLived.keySet().groupByMany { n -> citiesLived[n] }
> check(grouped3)
>
> def check(grouped) {
>     assert grouped == [
>         NY  : ['Alice', 'Bob'],
>         LA  : ['Alice', 'Cara'],
>         CHI : ['Cara']
>     ]
> }
>
> This is particularly useful for Eclipse Collections multimaps but maps
> with lists are common enough in Groovy even without explicit multimaps
> that I think this is valuable. You can think of it a little like the
> "inverse" method of a BiMap implementation but instead of inverting K
> and V we swap between K, List<V> to V, List<K>.
>
> Thoughts? I'll create a PR unless folks don't feel it adds enough
> value or want to comment on the proposed functionality and naming.
>
> Cheers, Paul.
>

Reply via email to