Scala has a function groupBy
on lists that accepts a function for extracting keys from list items, and returns another list where the items are tuples consisting of
We can also use the SQL-like then group by
syntax in list comprehension, which requires TransformListComp
language extension.
Since Scala groupBy
returns a Map
, we can call fromDistinctAscList
to convert the list comprehension to a Map
.
$ stack repl --package containers
Prelude> :set -XTransformListComp
Prelude> import Data.Map.Strict ( fromDistinctAscList, Map )
Prelude Data.Map.Strict> import GHC.Exts ( groupWith, the )
Prelude Data.Map.Strict GHC.Exts> :{
Prelude Data.Map.Strict GHC.Exts| scalaGroupBy f l =
Prelude Data.Map.Strict GHC.Exts| fromDistinctAscList
Prelude Data.Map.Strict GHC.Exts| [ (the key, value)
Prelude Data.Map.Strict GHC.Exts| | value <- l
Prelude Data.Map.Strict GHC.Exts| , let key = f value
Prelude Data.Map.Strict GHC.Exts| , then group by key using groupWith
Prelude Data.Map.Strict GHC.Exts| ]
Prelude Data.Map.Strict GHC.Exts| :}
Prelude Data.Map.Strict GHC.Exts> :type scalaGroupBy
scalaGroupBy :: Ord b => (t -> b) -> [t] -> Map b [t]
Prelude Data.Map.Strict GHC.Exts> scalaGroupBy (`mod` 2) [1, 2, 3, 4, 5, 6, 7, 8, 9]
fromList [(0,[2,4,6,8]),(1,[1,3,5,7,9])]
The only difference from Scala groupBy
is that the above implementation returns a sorted map instead of a hash map. For implementation that returns a hash map, see my other answer at https://stackoverflow.com/a/64204797/955091.