Haskell equivalent to Scala's groupBy

后端 未结 7 1818
孤街浪徒
孤街浪徒 2021-02-02 12:29

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

7条回答
  •  再見小時候
    2021-02-02 13:01

    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.

提交回复
热议问题