如果你在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的新手,所以对这个潜在的愚蠢问题道歉。
非常感谢
答案 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.List
或Map.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)
这是另一种方法:
示例:
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)
通过将头应用于结果列表得到的最少。