计算列表中的唯一元素

时间:2010-09-14 16:40:41

标签: list haskell unique

是否有标准高阶函数的直接组合来计算列表中的唯一元素?

例如

的结果
[1, 1, 4, 0, 4, 4]

会像

[(1,2), (4,3), (0,1)]

5 个答案:

答案 0 :(得分:15)

使用Data.Map和元组部分:

 count = Map.fromListWith (+) . map (, 1)

(如果您需要列表,请添加Map.toList。)

答案 1 :(得分:11)

如果订单不重要,则可行:

map (\xs@(x:_) -> (x, length xs)) . group . sort

group . sort将为您提供一个列表列表,其中所有彼此相同的元素被分组到相同的子列表中(没有排序,只有连续的相等元素将被组合在一起)。 map然后将每个子列表转换为(element, lengthOfSublist) - 元组。

如果要在第一次出现时对结果进行排序,可以在排序之前使用zip为每个元素添加索引,然后在分组后,再次按该索引排序,然后删除索引。 / p>

答案 2 :(得分:7)

最简单的方法是将项目按顺序排序,使用“group”将它们放入相等元素的子列表中,然后计算每个子列表中的项目。

map (\xs -> (head xs, length xs)) . group . sort

答案 3 :(得分:6)

如果列表仅包含整数,您也可以使用

 import qualified Data.IntMap as I

 countElems1 :: [Int] -> [(Int, Int)]
 countElems1 = I.toList . foldr (\k -> I.insertWith (+) k 1) I.empty 

(请记住使用优化进行编译,否则这将比group . sort方法慢2倍。使用-O2它会稍微快14%。)

您还可以使用其中一个multiset packages,这使得函数变得如此简单

 import qualified Math.Combinatorics.Multiset as S
 countElems4 = S.toCounts . S.fromList

但效率低下。

以上所有解决方案都忽略了原始订单。

答案 4 :(得分:1)

你所谈论的只是排序数据run length encoding:免费在线书籍Real World Haskell有一个great example of this。在将其放入runLengthEncoder之前,您需要对列表进行排序。