我正在尝试按列表中的项目进行过滤并逐行打印。这是我的代码:
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
在我的代码末尾声明。它应该是不言自明的,您可以使用 let
或 where
定义“局部变量”的语句。就品味而言,我更喜欢 where over let。
列表推导与过滤器:列表推导可以像过滤函数一样过滤列表。对于函数 f :: a -> Bool
, 和一个列表 xs :: [a]
filter f xs
与[x | x <- xs, f x]
相同.就品味而言,我更喜欢拼写 filter
在这种情况下,因为它非常清楚我正在过滤列表。
--
进一步推荐:使用记录语法
代替
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
- 等等
关于list - 对列表中的项目使用过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5955465/