如何在列表中搜索匹配的项目?

时间:2015-06-18 22:10:49

标签: list haskell abstract-data-type

我正在练习明天练习考试。 该文本告诉我将数据库实现到库中,以定义可以是书籍或杂志的Item。对于每本书,我保存了姓名+作者。每个Magazine我保存名称:

 data Item = Book String String
      | Magazine String
      deriving(Show)

data Requisition = Req String Item

type Database = [Requisition]

exDB :: Database
exDB = [Req "John" (Book "PF" "HS"),Req "Jay"(Book "Apple" "Steve Jobs"),Req "Francis"(Magazine "Forbes")]

books :: Database -> String -> [Item]
books db name = {-- what's next?-}

现在,我需要创建一个名为books :: Database -> String -> [Item]的函数,它在我的数据库中按名称搜索并向我提供该人请求的图书。

我该怎么做?

2 个答案:

答案 0 :(得分:5)

使用filter函数非常简单:

filter :: (a -> Bool) -> [a] -> [a]

它需要一个条件才能应用于列表的每个元素,然后返回满足该条件的所有元素的列表。在您的情况下,您想要查找特定人员所要求的书籍。你可以将其分解为两个问题:

  1. 查找给定人员的所有请求
  2. 查找Requisition列表
  3. 中的所有图书

    要解决第一个问题,我们说

    requestsFromPerson :: Database -> String -> Database
    requestsFromPerson db name = filter matchesName db
        where
            matchesName (Req name' item) = name == name'
    

    第二步也可以用filter完成,但我会让你填写实现

    onlyBooks :: Database -> Database
    onlyBooks db = filter ??? db
    

    然后你可以将这两者结合起来:

    books db name = onlyBooks (requestsFromPerson db name)
    

    所以你要做的就是为???填写onlyBooks,这应该有效!提示:模式匹配是你的朋友。

答案 1 :(得分:1)

books db name = [... | Req n b@(Book _ _) <- db, n==name]

使用列表推导,只会跳过不匹配的项目。模式可以嵌套。