我有一个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
具有最高计数。我该如何实现呢?
答案 0 :(得分:4)
我的建议是将问题分成两部分:
您可以将其设置为
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查找并理解compare
,on
和maximumBy
....这样的技巧可以真正缩短你的代码。
总而言之,您可以获得具有最大计数的条目
maxEntry = maximumBy (compare `on` count) $ filter ((theName ==) . name) $ entries
你需要修改这个以解决Nothing案例,或者你想要返回所有最大条目(这只是选择一个),或者你真的想要返回计数,而不是条目。