【问题标题】:How to get a item with the highest score from a list如何从列表中获得最高分的项目
【发布时间】:2014-12-21 06:15:36
【问题描述】:

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

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

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

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

有什么帮助吗?

【问题讨论】:

    标签: list haskell max


    【解决方案1】:

    过滤器和列表理解似乎都是正确的方法。

    没有。您希望将列表缩减为单个元素 (Item, Int) 并使用 fst。这不是过滤器,而是折叠。

    maximumBy 中有 Data.List

    maximumBy :: (a -> a -> Ordering) -> [a] -> a
    

    如果你有一个函数

    compareScore :: (Item, Int) -> (Item, Int) -> Ordering
    

    基于snd比较两对(Item, Int),你可以这样使用它:

    highestScoreItem = fst . maximumBy compareScore
    

    幸运的是,Data.Ord 中有 comparing,它可以让您根据可比较的事物来比较事物:

    compareScore = comparing snd
    

    这就是你所需要的。作为练习,尝试自己编写comparingmaximumBy,然后尝试仅使用foldr 解决问题。

    【讨论】:

    • 谢谢!我从来没有听说过 fold 但它似乎很有用......刚刚写完我自己的比较和最大值顺便说一句
    • @Elliot:折叠很常见。如果您关注 LYAH,您将在第 6 章中遇到 foldlfoldr
    【解决方案2】:

    您有一个元组列表,并希望根据元组的第二个元素选择最大值。

    您需要使用maximumBy 函数以及一个可以根据第二个元素进行比较的自定义比较器。

    import Data.Function (on)
    import Data.List (maximumBy)
    main = print $ fst (maximumBy (compare `on` snd) [(1, 5), (2, 1)])
    -- 1
    

    这里,

    maximumBy 从元组列表中获取每个元组,并调用比较器函数(compareonsnd),我们将其作为第一个参数传递,以获取要用于比较的实际值。

    我们使用snd 函数仅获取元组中的第二个元素进行比较。因此,maximumBy 仅使用所有元组的第二个元素进行比较,并获得最大值。但是您只需要最大元组的第一个元素。所以我们使用fst 函数只获取元组中的第一个元素。

    或者,您可以使用Data.ord 模块中的comparing 函数,就像这样

    import Data.Ord (comparing)
    import Data.List (maximumBy)
    main = print $ fst (maximumBy (comparing snd) [(1, 5), (2, 1)])
    -- 1
    

    【讨论】:

    • 非常有用的答案...使用maximum的好例子通过欢呼:)
    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 2012-03-06
    • 2019-11-21
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    相关资源
    最近更新 更多