list - 对列表中的项目使用过滤器?

标签 list haskell filter

我正在尝试按列表中的项目进行过滤并逐行打印。这是我的代码:

data Car = Car String [String] Int [String]

testDatabase :: [Car]
testDatabase = [Car"Casino Royale" ["Daniel Craig"] 2006 ["Garry", "Dave", "Zoe", "Kevin", "Emma"],Car"Blade Runner" ["Harrison Ford", "Rutger Hauer"] 1982 ["Dave", "Zoe", "Amy", "Bill", "Ian", "Kevin", "Emma", "Sam", "Megan"]]



formatCarRow (Car a b c d) =  show a ++ " | " ++ concat [i ++ ", " | i <- init b] ++ last b ++ " | " ++ show c ++ " | " ++ concat [j ++ ", " | j <- init d] ++ last d



displayFilmsByYear :: String -> IO [()]
displayFilmsByYear chosenYear = mapM (putStrLn.formatFilmRow) [putStrLn(filter ((== chosenYear).y)) |  (w x y z) <- testDatabase] -- This is the code not working i think

为什么这行不通?

最佳答案

如果你想过滤列表,我建议使用 filter函数:)

data Car = Car String [String] Int [String]

year :: Car -> Int
year (Car _ _ y _) = y

filterByYear :: Int -> [Car] -> [Car]
filterByYear chosenYear cars = filter (\car -> year car == chosenYear) cars

showCar :: Car -> String
showCar car = undefined -- you can implement this how you like

displayCarsByYear :: Int -> IO ()
displayCarsByYear chosenYear = mapM_ (putStrLn . showCar) filteredCars
    where filteredCars = filterByYear chosenYear testDatabase

在这里解释一些事情似乎是明智的:

匿名函数:(\car -> year car == chosenYear)是一个匿名函数。它接受一个参数并将其称为 car .然后它确定该汽车的年份是否等于 chosenYear .我没有明确写出这个函数的类型签名,但它是 Car -> Bool .

过滤:我把这个功能给了filter , 以便它查看 Car 的列表秒。当filter查找该函数返回 True 的汽车, 它将它们放入结果列表中。 False结果意味着汽车没有通过过滤器。

函数组成:(putStrLn . showCar)这是一个首先执行 showCar 的函数, 然后使用 putStrLn关于 showCar 的结果.

位置:您会注意到 where在我的代码末尾声明。它应该是不言自明的,您可以使用 letwhere定义“局部变量”的语句。就品味而言,我更喜欢 where over let。

列表推导与过滤器:列表推导可以像过滤函数一样过滤列表。对于函数 f :: a -> Bool , 和一个列表 xs :: [a]

filter f xs[x | x <- xs, f x]相同.就品味而言,我更喜欢拼写 filter在这种情况下,因为它非常清楚我正在过滤列表。

另见 LYAH # Maps and filters

--

进一步推荐:使用记录语法

代替

data Car = Car String [String] Int [String]

为什么不

data Film = Film { name :: String
                 , actors :: [String]
                 , released :: Int
                 , characters :: [String]
                 }

(我真的不知道你最后的字符串列表是什么)

通过这种方式,您可以构建这样的电影:

lotr :: Film
lotr = Film { name = "Lord of the Rings"
            , actors = ["Elijah Wood", "Ian McKellen", "Orlando Bloom"]
            , released = 2001
            , characters = ["Frodo", "Sam", "Pippin", "Merry"]
            }

并且你自动拥有访问函数

  • released :: Film -> Int
  • name :: Film -> String
  • 等等

另见 LYAH # Record syntax

关于list - 对列表中的项目使用过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5955465/

相关文章:

haskell - 导入单子(monad)状态

haskell - 使用 GADT 进行类型推断 - a0 是不可触及的

java - MongoDB查询嵌套键值并比较内部值列表

R lazyeval:将参数传递给 dplyr::filter

python - 所有排列的列表,但没有相反的数字

python - 将数组列表合并为一个数组列表

list - 为什么我的谓词在序言中返回列表列表?

python - 比较列表(A)中的项目是否作为列表(B)中的子项目存在

haskell - 代数解释多态性

web-applications - 如何为高流量 webapp 实现 'saved search' 功能?