查找具有最高计数的列表条目

时间:2014-05-29 16:03:17

标签: haskell

我有一个Entry数据类型

data Entry = Entry {
    count :: Integer,
    name :: String }

然后我想编写一个函数,它将Entry s的名称和列表作为参数给我Entry s具有最高计数。到目前为止我所拥有的是

searchEntry :: String -> [Entry] -> Maybe Integer
searchEntry _ [] = Nothing
searchEntry name1 (x:xs) = 
   if name x == name1
       then Just (count x)
       else searchEntry name xs 

这给了我函数找到的第一个Entry,但我希望Entry具有最高计数。我该如何实现呢?

3 个答案:

答案 0 :(得分:4)

我的建议是将问题分成两部分:

  1. 查找与给定名称匹配的所有条目
  2. 查找计数最高的条目
  3. 您可以将其设置为

    entriesByName :: String -> [Entry] -> [Entry]
    entriesByName name entries = undefined
    
    -- Use Maybe since the list might be empty
    entryWithHighestCount :: [Entry] -> Maybe Entry
    entryWithHighestCount entries = undefined
    
    entryByNameWithHighestCount :: String -> [Entry] -> Maybe Entry
    entryByNameWithHighestCount name entires = entryWithHighestCount $ entriesByName name entries
    

    您所要做的就是实现用于实现getEntryByNameWithHighestCount的相对简单的函数。

答案 1 :(得分:0)

您需要添加一个内部方法,该方法将当前结果作为参数,并在到达方法末尾时返回而不是Nothing

此外,您需要更新结果找到的逻辑,以比较可能存在的函数和找到的值。

答案 2 :(得分:0)

如果您确实想要返回"条目"我会考虑将函数的签名更改为String->Maybe Entry(或String->[Entry])。计数最多的项目。

否则,您可以使用一些非常常见的Haskell函数来实际执行您想要的oneliner ....

正如Bheklilr所说,名称过滤器可以先完成,使用filter函数很容易做到这一点....

filter (hasName theName) entries

请注意,hasName可以作为单独的函数完全写出,但Haskell还为您提供了以下快捷方式。

hasName = (== theName) . name

现在你只需要最大值.... Haskell有一个maximum函数,但它只适用于Ord类。您可以将Entry作为Ord的实例,或者您可以使用相关的maximumBy函数,该函数需要额外的排序函数

maximumBy orderFunction entries2

同样,你可以自己写orderFunction(你可能想做一个练习),但是haskell再次提供了一个快捷方式。

orderFunction = compare `on` count

您需要导入一些lib才能使这一切工作(Data.Function,Data.List)。您还需要输入一些额外的代码来解释Nothing案例。

首先写出函数可能是值得的,但我建议您使用Hoogle查找并理解compareonmaximumBy ....这样的技巧可以真正缩短你的代码。

总而言之,您可以获得具有最大计数的条目

maxEntry = maximumBy (compare `on` count) $ filter ((theName ==) . name) $ entries

你需要修改这个以解决Nothing案例,或者你想要返回所有最大条目(这只是选择一个),或者你真的想要返回计数,而不是条目。