如何从列表中获得分数最高的项目

时间:2014-12-21 06:15:36

标签: list haskell max

我在Haskell中有一个[(item, score)]结构的列表。

highestScoreItem :: [(Item, Int)] -> Item

highestScoreItem是一个获取(Item,Int)列表的函数,并返回得分最高的项目。

我尝试了头尾递归,但仍然无法完成功能。过滤器和列表理解似乎都是正确的方法,但我绝对不够先进,无法使用它....

请帮忙吗?

2 个答案:

答案 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

这就是你所需要的。在练习时,请尝试自己编写comparingmaximumBy,然后尝试仅使用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