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

假设 range=2,并使用前面的列表,会给我 [1, 4, 2, 1] ,因为有 1 个 0 或 1、4 个 2 或 3、2 个 4 或 5 和 1 个 6 或 7。

假设 range=4,并使用前面的列表,将给我 [5, 3],因为有 5 个 0 或 1 或 2 或 3,3 个 4 或 5 或 6 或 7。

我查看了 groupgroupBy 但没有找到合适的谓词,还有 histogram-fill 库。后者似乎很适合创建垃圾箱,但我不知道如何将数据加载到这些垃圾箱中。

我怎样才能做到这一点?

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

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,2,3],[4]] 时,输出是 [[1,2,3],[4],[2]]。下面的两个建议都适用于排序列表。
main = print (groupBy ((==) `on` quantize 4) (sort [1,2,3,4,2]))

最佳答案

您需要进行量化才能获得 bin 的定义。

-- `quantize range n` rounds n down to the nearest multiple of range
quantize :: Int -> Int -> Int
groupBy 接受一个“谓词”参数*,它标识两个项目是否应该放在同一个 bin 中。所以:
groupBy (\n m -> quantize range n == quantize range m) :: [Int] -> [[Int]]

将根据元素是否在同一个 bin 中对元素进行分组,而不更改元素。如果 range 是 2,那会给你类似的东西
[[1],[2,2,3,3],[4,5],[6]]

然后你只需要获取每个子列表的 length

* 有一个名为 on 的简洁函数,它允许您更简洁地编写谓词
groupBy ((==) `on` quantize range)

关于haskell - 如何在haskell中分组和计数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32300651/

10-13 06:24
查看更多