Len*_*low 12 haskell list unique
是否有标准高阶函数的直接组合来计算列表中的唯一元素?
例如,结果为
[1, 1, 4, 0, 4, 4]
Run Code Online (Sandbox Code Playgroud)
会是这样的
[(1,2), (4,3), (0,1)]
Run Code Online (Sandbox Code Playgroud)
sdc*_*vvc 15
使用Data.Map和元组部分:
count = Map.fromListWith (+) . map (, 1)
Run Code Online (Sandbox Code Playgroud)
(Map.toList
如果需要列表,请添加.)
sep*_*p2k 11
如果订单不重要,这有效:
map (\xs@(x:_) -> (x, length xs)) . group . sort
Run Code Online (Sandbox Code Playgroud)
group . sort
将给出一个列表列表,其中所有彼此相同的元素被分组到相同的子列表中(没有排序,只有连续的相等元素将被组合在一起).在map
然后转向每个子列表成(element, lengthOfSublist)
元组.
如果zip
要按第一次出现的顺序排序,可以在排序之前使用,为每个元素添加索引,然后在分组后,再次按该索引排序,然后删除索引.
最简单的方法是将项目按顺序排序,使用"group"将它们放入相等元素的子列表中,然后计算每个子列表中的项目.
map (\xs -> (head xs, length xs)) . group . sort
Run Code Online (Sandbox Code Playgroud)
如果列表只包含整数,您也可以使用
import qualified Data.IntMap as I
countElems1 :: [Int] -> [(Int, Int)]
countElems1 = I.toList . foldr (\k -> I.insertWith (+) k 1) I.empty
Run Code Online (Sandbox Code Playgroud)
(请记住使用优化进行编译,否则这将比group . sort
方法慢2 -O2
倍.稍微快14%.)
import qualified Math.Combinatorics.Multiset as S
countElems4 = S.toCounts . S.fromList
Run Code Online (Sandbox Code Playgroud)
但效率较低.
所有上述解决方案都忽略了原始订单.