问题描述
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 $ / code>
c $ c>代替,但那不重要)。 C#有一个更有用的版本,可以让你同时映射这些值(如果你的关键函数只是提取元组的一部分,非常有用)。
Haskell有一个
groupBy
,但它有些不同 - 它根据一些比较函数对事物进行分组。
在我写和写之前,Haskell中是否有相当于Scala的 groupBy
? Hoogle对于我所期望的签名看起来像(下面)没有任何东西,但我可能错了。
等式b => (a - > b) - > [a] - > [(b,[a])]
解决方案自己编写函数很容易,但是您需要在分类器函数的结果中放置 Ord
或 Hashable
约束如果你想要一个有效的解决方案例子:
import Control.Arrow((&&& amp; amp; amp;))
import Data.List
导入Data.Function
myGroupBy ::(Ord b)=> (a - > b) - > [a] - > [(b,[a])]
myGroupBy f =地图(f。head&& amp;& amp; id)
。 groupBy((==)``f)
。 sortBy(比较'f`)
> myGroupBy(`mod` 2)[1..9]
[(0,[2,4,6,8]),(1,[1,3,5,7,9])]
您也可以使用像 Data.HashMap.Strict
而不是按期望的线性时间进行排序。
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 the key and the list of items producing that key. In other words, something like this:
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)))
(Actually, it looks like in current versions it provides a Map
instead, but that's not important). C# has an even more useful version that lets you map the values at the same time (very useful if, say, your key function is just extracting part of a tuple).
Haskell has a groupBy
, but it's somewhat different - it groups runs of things according to some comparison function.
Before I go and write it, is there an equivalent of Scala's groupBy
in Haskell? Hoogle doesn't have anything for what I'd expect the signature to look like (below), but I may have just got it wrong.
Eq b => (a -> b) -> [a] -> [(b,[a])]
解决方案 You can write the function yourself rather easily, but you need to place an Ord
or Hashable
constraint on the result of the classifier function if you want an efficient solution. Example:
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])]
You can also use a hash map like Data.HashMap.Strict
instead of sorting for expected linear time.
这篇关于Haskell相当于Scala的groupBy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!