用于显示列表中表示最低元素的函数

时间:2012-02-18 11:15:00

标签: haskell

如果你在Haskell中有这样的列表:

data TestType = A | B | C deriving (Ord, Eq, Show) 

List1 :: [TestType]
List1 = [A,B,C,B,C,A,B,C,C,C]

是否可以编写一个函数来确定哪个元素在列表中表示最少(所以在这种情况下为'A')

我最初的想法是编写一个这样的辅助函数,但现在我不确定这是否是正确的方法:

appears :: TestType -> [TestType] -> Int
appears _ [] = 0
appears x (y:ys) | x==y = 1 + (appears x ys)
                 | otherwise = appears x ys

我仍然是Haskell的新手,所以对这个潜在的愚蠢问题道歉。

非常感谢

4 个答案:

答案 0 :(得分:7)

Matt的方法略有替代版本

import Data.List
import Data.Ord

leastFrequent :: Ord a => [a] -> a
leastFrequent = head . minimumBy (comparing length) . group . sort

答案 1 :(得分:2)

您可以构建一张地图,计算每个项目在列表中出现的频率

import qualified Data.Map as Map

frequencies list = Map.fromListWith (+) $ zip list (repeat 1)

然后,您可以在频率图的minimumBy列表中使用maximumBy中的Data.ListMap.assocs找到最少/最多代表,或者甚至按频率对其进行排序使用sortBy

module Frequencies where

import Data.Ord
import Data.List
import qualified Data.Map as Map

frequencyMap :: Ord a => [a] -> Map.Map a Int
frequencyMap list = Map.fromListWith (+) $ zip list (repeat 1)

-- Caution: leastFrequent will cause an error if called on an empty list!
leastFrequent :: Ord a => [a] -> a
leastFrequent = fst . minimumBy (comparing snd) . Map.assocs . frequencyMap

ascendingFrequencies :: Ord a => [a] -> [(a,Int)]
ascendingFrequencies = sortBy (comparing snd) . Map.assocs . frequencyMap

答案 2 :(得分:2)

这是另一种方法:

  1. 对列表进行排序
  2. 将列表分组
  3. 找到每组的长度
  4. 返回长度最短的群组
  5. 示例:

    import GHC.Exts
    import Data.List
    
    fewest :: (Eq a) => [a] -> a
    fewest xs = fst $ head sortedGroups 
    where 
      sortedGroups = sortWith snd $ zip (map head groups) (map length groups)
      groups = group $ sort xs
    

答案 3 :(得分:1)

一个不太优雅的想法是:

  • 首先对列表进行排序和分组
  • 然后将案例与其陈述的数量配对
  • 最后将它们相对于它们的表示数
  • 进行排序

在代码中,这看起来像

import Data.List                                                                 

sortByRepr :: (Ord a) => [a] ->[(a,Int)]
sortByRepr xx = sortBy compareSnd $ map numOfRepres $ group $ sort xx
              where compareSnd x y = compare (snd x) (snd y)
                    numOfRepres x = (head x, length x)

通过将头应用于结果列表得到的最少。