我有一个名为Person
的代数数据类型如下:
data Person =
Person { firstName :: String
, lastName :: String
, height :: Float
, age :: Int
} deriving (Show, Eq)
我还有一个Person
列表,其中包含有关人员的各种信息,现在说我想仅根据Person
返回一个特定firstName
的所有数据,我该怎么办?那样做?
搜索列表中存储的所有firstName
,然后在查询匹配时返回Just Person
,如果没有匹配则返回Nothing
答案 0 :(得分:4)
您可以使用filter
返回包含Person
上具有给定条件的所有firstName
的列表。
例如:
filter (\x -> firstName x == "John") xs
其中xs
包含Person
列表。如果没有[]
符合条件,这将返回一个空列表(Person
)。
答案 1 :(得分:1)
很简单,您可以编写自定义查找功能:
lookupBy :: Eq b => (a -> b) -> [a] -> b -> Maybe a
lookupBy _ [] _ = Nothing
lookupBy f (x:xs) key = if f x == key then Just x else lookupBy f xs key
然后你可以用它作为
main = do
let people = [Person "John" "Doe" 68 30, Person "Jane" "Smith" 63 28]
print $ lookupBy firstName people "Jane"
print $ lookupBy lastName people "Doe"
print $ lookupBy age people 29
print $ lookupBy height people 63
这会打印
Just (Person {firstName="Jane", lastName="Smith", height=63, age=28})
Just (Person {firstname="John", lastName="Doe", height=58, age=30})
Nothing
Just (Person {firstName="Jane", lastName="Smith", height=63, age=28})
(假设它编译,我没有运行此代码,但它应该工作)。
如果您想选择是获得单个项目还是匹配项目列表,您可以
import Data.Maybe (listToMaybe)
lookupAllBy :: Eq b => (a -> b) -> [a] -> b -> [a]
lookupAllBy f xs key = filter (\x -> f x == key) xs
lookupBy :: Eq b => (a -> b) -> [a] -> b -> Maybe a
lookupBy f xs key = listToMaybe $ lookupAllBy f xs key