我在Haskell中有一个[(item, score)]
结构的列表。
highestScoreItem :: [(Item, Int)] -> Item
highestScoreItem
是一个获取(Item,Int)列表的函数,并返回得分最高的项目。
我尝试了头尾递归,但仍然无法完成功能。过滤器和列表理解似乎都是正确的方法,但我绝对不够先进,无法使用它....
请帮忙吗?
答案 0 :(得分:6)
过滤器和列表理解似乎都是正确的方法。
没有。您希望将列表缩减为单个元素(Item, Int)
并使用fst
。这不是过滤器,而是折叠。
Data.List
中有maximumBy
:
maximumBy :: (a -> a -> Ordering) -> [a] -> a
如果你有一个功能
compareScore :: (Item, Int) -> (Item, Int) -> Ordering
比较基于(Item, Int)
的两对snd
,您可以像这样使用它:
highestScoreItem = fst . maximumBy compareScore
幸运的是,Data.Ord
中有comparing
,可让您根据可比较的内容进行比较:
compareScore = comparing snd
这就是你所需要的。在练习时,请尝试自己编写comparing
和maximumBy
,然后尝试仅使用foldr
来解决问题。
答案 1 :(得分:2)
您有一个元组列表,并希望根据元组的第二个元素选择最大值。
您需要使用maximumBy
函数以及可以根据第二个元素进行比较的自定义比较器。
import Data.Function (on)
import Data.List (maximumBy)
main = print $ fst (maximumBy (compare `on` snd) [(1, 5), (2, 1)])
-- 1
在这里,
maximumBy
从元组列表中获取每个元组并调用我们作为第一个参数传递的(compare
上的比较器函数snd)
,以获取要使用的实际值在比较中。
我们使用snd
函数只获取元组中的第二个元素进行比较。因此,maximumBy
仅使用所有元组的第二个元素进行比较,并获得最大值。但是你只需要最大元组的第一个元素。所以我们使用fst
函数只获取元组中的第一个元素。
或者,您可以使用comparing
模块中的Data.ord
函数,例如
import Data.Ord (comparing)
import Data.List (maximumBy)
main = print $ fst (maximumBy (comparing snd) [(1, 5), (2, 1)])
-- 1