Haskell:在元组中搜索fst并显示snd

时间:2014-03-10 19:32:01

标签: haskell

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

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 它将归还艾米所评定的所有电影(Blade Runner& The Fly)

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

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

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

我的问题:

我需要将上面的函数更改为只返回一个int,即元组'user'(amy)所在的元组中'snd'的int。即 我需要:

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

以下功能是您可以在上下文中看到的:

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

到目前为止,上述内容将归还Amy所评价的影片中的所有评分,

但是,我只想要她的收视率。 我希望我已经解释了这一点,我的英语不是很好。

谢谢,

麦克

2 个答案:

答案 0 :(得分:4)

您正在寻找的功能称为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

答案 1 :(得分: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。