I created GROOVY-11808 and this initial PR to help with gaining feedback:

https://github.com/apache/groovy/pull/2343

I haven't checked whether a few more variants make sense, e.g. Maps or
Arrays?, but thought having a concrete initial implementation might be
useful for any further feedback.

Cheers, Paul.

On Wed, Nov 26, 2025 at 8:32 PM Søren Berg Glasius <[email protected]> wrote:
>
> I agree, looks good to me!
>
> Den ons. 26. nov. 2025 kl. 08.46 skrev Guillaume Laforge <[email protected]>:
>>
>> This sounds like a great addition!
>> Naming is consistent with our existing methods.
>>
>> Guillaume
>>
>>
>> Guillaume Laforge
>> Apache Groovy committer
>> Developer Advocate @ Google Cloud
>>
>> Blog: glaforge.dev
>> X: @glaforge
>> Bluesky: @glaforge.dev
>> Mastodon: @[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.
>
>
>
> --
>
> Med venlig hilsen,
> Søren Berg Glasius
>
> Hedevej 1, Gl. Rye, 8680 Ry
> Mobile: +45 40 44 91 88
> --- Press ESC once to quit - twice to save the changes.

Reply via email to