哈斯克尔相当于Scala的GROUPBY(Haskell equivalent to Scala&#

2019-08-17 14:48发布

Scala有一个功能groupBy上列出了接受从列表项中提取密钥的功能,并返回另一个列表,其中的项目包括关键和生产是关键的项目列表的元组。 换句话说,这样的事情:

List(1,2,3,4,5,6,7,8,9).groupBy(_ % 2)
// List((0, List(2,4,6,8)), (1, List(1,3,5,7,9)))

(事实上,它看起来像在当前版本中,它提供了一个Map ,而不是,但是这并不重要)。 C#有一个更加有用的版本,可以让你的价值观,同时映射(如果说是非常有用的,你的关键功能只提取元组的一部分)。

Haskell有一个groupBy ,但它有点不同-这组根据一些比较函数的东西运行。

我去写它之前,有没有Scala的的等效groupBy在Haskell? Hoogle没有什么我期望的签名看起来像(下)什么,但我可能刚刚听错了。

Eq b => (a -> b) -> [a] -> [(b,[a])]

Answer 1:

你可以比较容易地编写自己的功能,但你需要放置OrdHashable ,如果你想要一个有效的解决方案的约束对分类函数的结果。 例:

import Control.Arrow ((&&&))
import Data.List
import Data.Function

myGroupBy :: (Ord b) => (a -> b) -> [a] -> [(b, [a])]
myGroupBy f = map (f . head &&& id)
                   . groupBy ((==) `on` f)
                   . sortBy (compare `on` f)

> myGroupBy (`mod` 2) [1..9]
[(0,[2,4,6,8]),(1,[1,3,5,7,9])]      

你也可以使用一个哈希表像Data.HashMap.Strict ,而不是为预期的线性时间排序。



Answer 2:

具体来说,有以下应该工作:

scalaGroupBy f = groupBy ((==) `on` f) . sortBy (comparing f)

模,这并不让你的结果f每个组中,但如果你真的需要它,你可以随时后期处理与

map (\xs -> (f (head xs), xs)) . scalaGroupBy f


Answer 3:

这是不是在列表库中的函数。

你可以把它写成sortBy和GROUPBY的组成。



Answer 4:

把一个tracef表明,与@Niklas溶液, f评估3次,长度为2或更多的任何列表上的每个元件。 我把以便修改它的自由f被施加到每个元件仅一次。 目前尚不清楚创建和销毁元组的成本。但是是否小于评估的成本f多次(因为f可任意)。

import Control.Arrow ((&&&))
import Data.List
import Data.Function

myGroupBy' :: (Ord b) => (a -> b) -> [a] -> [(b, [a])]
myGroupBy' f = map (fst . head &&& map snd)
                   . groupBy ((==) `on` fst)
                   . sortBy (compare `on` fst)
                   . map (f &&& id)


Answer 5:

该解决方案将打破和组由(FX),不管阉是排序或不

f = (`mod` (2::Int))

list = [1,3,4,6,8,9] :: [Int]


myGroupBy :: Eq t => (b -> t) -> [b] -> [(t, [b])]

myGroupBy f (z:zs) = reverse $ foldl (g f) [(f z,[z])] zs
  where
    -- folding function                        
    g f ((tx, xs):previous) y = if (tx == ty)
                           then (tx, y:xs):previous
                           else (ty, [y]):(tx, reverse xs):previous
        where ty = f y                        

main = print $ myGroupBy f list

结果:[(1,[1,3]),(0,[4,6,8]),(1,[9])]



文章来源: Haskell equivalent to Scala's groupBy
标签: scala haskell