现在我要计算列表中最常见的项目 我是一步一步做到的。
group :: Eq a => [a] -> [[a]]
group = groupBy (==)
-- | The 'groupBy' function is the non-overloaded version of 'group'.
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy _ [] = []
groupBy eq (x:xs) = (x:ys) : groupBy eq zs
where (ys,zs) = span (eq x) xs
task4 xs = (map (\l@(x:xs) -> (x,length l)) (group (sortList xs)))
<main> task4 [1,1,1,2,2,3]
[(1,3),(2,2),(3,1)]
答案 0 :(得分:4)
让我们首先假设您只对模式出现的频率感兴趣。所以你只需要使用
map length . group $ sortList xs
列出各个组的长度列表。那么剩下要做的就是检索maximum
。
现在,这不是你想要的全部。基本上,您需要最大的元组列表,但它应仅比较长度字段,而不是元素1。因此,你可能会被hoogle for Ord b => [(a, b)] -> a
(或-> (a,b)
)所诱惑,但没有这样的标准功能。
但是,由于您已经搜索到了最大值,并且这种特殊形式正是您想要的,您可以向下滚动该结果页面,然后您将找到maximumBy
。它允许您指定哪个&#34;属性&#34;应考虑进行比较。
使用它的首选方法是相当不言自明的
GHCI&GT; :m + Data.Ord Data.List
GHCI&GT; :t maximumBy(比较snd)
maximumBy(比较snd):: Ord a =&gt; [(a1,a)] - &gt; (a1,a)
因此,我们正在处理如何访问关键字段作为函数参数的信息。好吧,但由于snd
本身就是一个功能,我们也可以使用任何其他功能!因此,首先没有真正需要建立elem + runlength元组,你可能只是这样做
maximumBy (comparing length) . group $ sort xs
给出了正确的结果(尽管效率稍差)。简而言之:
mode :: Ord a => [a] -> a
mode = maximumBy (comparing length) . group . sort
答案 1 :(得分:2)
你非常接近。如果不是:
(\l@(x:xs) -> (x,length l))
你写道:
(\l@(x:xs) -> (length l,x))
然后你只需要输出maximum
:
maximum [(3,1),(2,2),(1,3)] == (3,1)