给定一个列表(例如 [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。
我查看了 group
和 groupBy
但没有找到合适的谓词,还有 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/