【问题标题】:Haskell: searching though fst in a tuple and displaying the sndHaskell:在元组中搜索 fst 并显示 snd
【发布时间】:2014-03-10 19:32:00
【问题描述】:

我有一个这样的电影数据库:

testDatabase = [("Blade Runner", "Ridley Scott", 1982, [("Amy",6), ("Bill",9), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",5), ("Megan",4)]),
("The Fly", "David Cronenberg", 1986, [("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",5)])]

它包含两部电影的格式:“标题”、“导演”、“年份”、“用户评分”

type UserRating = [(String, Int)]

我有一个名为“displayAllFilms”的函数,它将以格式化字符串显示每部电影。 和一个函数“hasUserRated”,如果用户已评分,则返回 Bool:

hasUserRated :: String -> Film -> Bool
hasUserRated user (_, _, _, userrating)
        | elem user (map fst (userrating)) = True
        | otherwise                        = False

如果我这样做:displayAllFilms $ filter (hasUserRated "Amy") database 它将返回所有艾米评分的电影(银翼杀手和苍蝇)

当它找到 Amy 的元组时,我还需要显示评分。

为了解决这个问题,我有一个名为 whatUserRated 的函数:

    whatUserRated ::  String -> Film -> [Int]
    whatUserRated user (_, _, _, userrating)
         | elem user (map fst (userrating)) = map snd userrating

我的问题:

我需要将上述函数更改为只返回一个 int,即找到元素 'user' (amy) 的元组中的 'snd' 的 int。 IE 我需要:

WhatUserRated "Amy"(我需要过滤器的结果作为第二个参数)

下面的函数可以让你在上下文中看到它:

userRatedFilms :: String -> Database -> String
userRatedFilms user database = displayAllFilms $ map (whatUserRated "Amy") $ filter (hasUserRated "Amy") testDatabase

到目前为止,上面将返回艾米已评分的电影中的所有评分,

但是,我只想要她的评分。 我希望我已经解释得够多了,我的英语不是很好。

谢谢,

迈克。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    您要查找的函数名为lookup。它有类型

    lookup :: Eq a => a -> [(a, b)] -> Maybe b
    

    基本上,它接受一个关联列表并返回给定键与其中一个元组中的第一个元素匹配的第一个结果。如果没有找到这样的元组,则返回Nothing。一个示例用法是

    > lookup 3 [(1, "One"), (2, "Two"), (3, "Three")]
    Just "Three"
    > lookup 4 [(1, "One"), (2, "Two"), (3, "Three")]
    Nothing
    

    Maybe 数据类型的一个方便之处是您可以使用它来过滤和查找数据。如果操作返回Nothing,则丢弃它,否则使用该值。例如,您可以将函数编写为

    whatUserRated :: String -> Film -> Maybe Int
    whatUserRated = user (_, _, _, userrating) = lookup user userrating
    
    hasUserRated :: String -> Film -> Bool
    hasUserRated user film = isJust $ whatUserRated user film
    

    只要确保导入Data.Maybe

    【讨论】:

      【解决方案2】:

      使用lookup:

      whatUserRated ::  String -> Film -> Maybe Int
      whatUserRated user (_, _, _, userrating) = lookup user userrating
      

      whatUserRated 现在返回 Maybe Int,因为用户可能没有对特定电影评分(这意味着您不需要先检查它)。

      第二个函数现在简化为:

      userRatedFilms :: String -> Database -> String
      userRatedFilms user database = displayAllFilms $ mapMaybe (whatUserRated user) testDatabase
      

      mapMaybe 获取可能值的列表,并仅返回实际包含数据的值(Just 值)。您需要添加 import Data.Maybe 才能获取 mapMaybe。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-27
        • 1970-01-01
        • 2011-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多