如何在haskell中分组和计数?

如何在haskell中分组和计数?,haskell,Haskell,给定一个列表(例如[1,2,2,3,3,4,5,6]),如何根据箱子/范围对它们进行分组和计数?我希望能够指定一个范围,以便: 假设range=2,并使用前面的列表,将给出[1,4,2,1],假设存在10或1、42或3、24或5以及16或7 假设range=4,使用前面的列表,会给我[5,3],假设有50或1或2或3,34或5或6或7 我查看了group和groupBy但没有找到合适的谓词,也没有找到直方图填充库。后者似乎非常适合创建容器,但我无法找到如何将数据加载到这些容器中 我怎样才能做到这

给定一个列表(例如
[1,2,2,3,3,4,5,6]
),如何根据箱子/范围对它们进行分组和计数?我希望能够指定一个范围,以便:

假设range=2,并使用前面的列表,将给出
[1,4,2,1]
,假设存在10或1、42或3、24或5以及16或7

假设range=4,使用前面的列表,会给我[5,3],假设有50或1或2或3,34或5或6或7

我查看了
group
groupBy
但没有找到合适的谓词,也没有找到直方图填充库。后者似乎非常适合创建容器,但我无法找到如何将数据加载到这些容器中

我怎样才能做到这一点

我对以下建议之一的尝试:

import Data.List 
import Data.Function 

quantize range n = n `div` range  

main = print (groupBy ((==) `on` quantize 4) [1,2,3,4,2]) 
输出为[[1,2,3],[4],[2]],而它本应为[[1,2,2,3],[4]]。下面的两个建议都适用于已排序的列表

main = print (groupBy ((==) `on` quantize 4) (sort [1,2,3,4,2]))   

您可以使用
groupBy
div
功能实现这一点。假设我们有一个范围
N
。如果我们得到
N
连续数的整数除法(
div
),那么所有这些都应该相等。例如,
N=3
0div3=0,1div3=0,2div3=0,3div3=1,4div3=1,5div3=1,6div3=2

知道了这一点,我们可以查看
groupBy::(a->a->Bool)->[a]->[[a]]]
并使用以下函数:

sameGroup :: Integral a => a -> a -> a -> Bool
sameGroup range a b = a `div` range == b `div` range
编写我们自己的分组函数

groupings :: Integral a => a -> [a] -> [[a]]
groupings range = groupBy (sameGroup range)
这应该类似于
分组2[1,2,2,3,3,4,5,6]==[[1],[2,2,3,3],[4,5],[6]
。现在我们只需要计算它就可以得到最终的函数

groupAndCount :: Integral a => a -> [a] -> [Int]
groupAndCount range list = map length $ groupings range list

它应该反映所需的行为。

您需要量化以获得箱子的定义

-- `quantize range n` rounds n down to the nearest multiple of range
quantize :: Int -> Int -> Int
groupBy
接受一个“谓词”参数*,该参数标识两个项目是否应放在同一个箱子中。因此:

groupBy (\n m -> quantize range n == quantize range m) :: [Int] -> [[Int]]
将根据元素是否在同一个容器中对其进行分组,而不更改元素。如果
range
为2,则会得到如下结果

[[1],[2,2,3,3],[4,5],[6]]
然后您只需获取每个子列表的
长度

*有一个名为neat的函数,它允许您更简洁地编写谓词

groupBy ((==) `on` quantize range)

谢谢你们两位对我的问题的简单性质做出了非常好和彻底的回答(我是哈斯克尔的新手)。明天我会选择一个答案(我想这两个答案都是有效的)。我需要试用Mephy的答案,因为我不太习惯$(我想我现在需要声明分组采用两个参数)。@hotGopher这就是所谓的。量化是在库中定义的?不,它作为练习保留。啊,好的。我只是好奇。上面帖子中的“div”似乎是一个很好的线索。