映射#
简介#
关联列表:即一个键值相对应的列表,类似于其他语言中的字典或哈希表;
在 Haskell 中,原始的关联列表以序对列表的形式呈现;
[(key, value), ...]
一个序对即一个键值对;
exp1 = [("Math", 82), ("English", 94), ("History", 83)]
这种序对列表不保证键的唯一性;
exp2 = [("Math", 82), ("Math", 84)]
Data.List
的lookup
函数能在序对列表中根据序对的第一个值(键)查询第二个值(值);-- lookup :: Eq a => a -> [(a, b)] -> Maybe b exp3 = lookup 3 [(3, 4), (1, 2)] -- Just 4
Data.Map
模块实现了严格关联列表,称为映射,数据类型为Map k a
;当键为
Ord
类型类成员时,应当始终使用Data.Map
模块来处理键值对数据;
定义#
-
Data.Map.
fromList
:: Ord k => [(k, a)] -> Map k a# 接受一个序对列表,将其转换为映射,转换时忽略重复的键。
根据
fromList
函数的签名,序对中的键必须为Ord
类型类的成员,因为fromList
函数按树状排列键值对(有序)。import qualified Data.Map as M exp1 = M.fromList [(1, 2), (3, 4), (3, 2), (5, 5)] -- fromList [(1,2),(3,4),(5,5)]
-
Data.Map.
fromListWith
:: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a# 与
fromList
函数类似,但接受一个函数,当两个键重复时,该函数负责处理重复的键对应的两个值。phoneBook :: [(String, String)] phoneBook = [ ("betty", "555-2938") , ("betty", "342-2492") , ("bonnie", "452-2928") ] exp2 = M.fromListWith (\n1 n2 -> n1 ++ ", " ++ n2) phoneBook -- fromList [("betty","342-2492, 555-2938"),("bonnie","452-2928")]
-
Data.Map.
empty
:: Map k a# 空映射。
exp3 = M.empty -- fromList []
-
Data.Map.
singleton
:: k -> a -> Map k a# 接受一个键和一个值,返回包含该键值对的映射。
exp4 = M.singleton 3 9 -- fromList [(3,9)]
访问#
-
Data.Map.
lookup
:: Ord k => k -> Map k a -> Maybe a# 与
Data.List.lookup
函数类似,但作用于映射。exp5 = M.lookup 3 $ M.fromList [(2, 5), (3, 4)] -- Just 4
-
Data.Map.
keys
:: Map k a -> [k]# 以列表方式返回映射的所有键。
exp6 = M.keys $ M.fromList [(1, 2), (3, 4), (5, 6)] -- [1,3,5]
-
Data.Map.
elems
:: Map k a -> [a]# 以列表方式返回映射的所有值。
添加#
-
Data.Map.
insert
:: Ord k => k -> a -> Map k a -> Map k a# 接受一个键、一个值和一个映射,将键值对插入到映射结尾并返回一个新映射。
exp7 = M.insert 3 100 M.empty -- fromList [(3,100)]
删除#
-
Data.Map.
delete
:: Ord k => k -> Map k a -> Map k a# 接受一个键和一个映射,删除映射中的键及其对应值并返回新映射。
exp9 = M.delete 5 $ M.fromList [(5, 'a'), (3, 'b')] -- fromList [(3,'b')]
-
Data.Map.
deleteAt
:: Int -> Map k a -> Map k a# 接受一个索引值(从 0 开始)和一个映射,删除对应索引的键值对,超过索引值则报错。
exp10 = M.deleteAt 0 $ M.fromList [(1, 'a'), (2, 'b')] -- fromList [(2,'b')]
判断#
-
Data.Map.
null
:: Map k a -> Bool# 判断映射是否为空。
exp11 = M.null M.empty -- True exp12 = M.null $ M.insert 3 100 M.empty -- False
-
Data.Map.
member
:: Ord k => k -> Map k a -> Bool# 判断键是否存在于映射中。
exp13 = M.member 3 $ M.fromList [(3, 6), (4, 5)] -- True
重构#
-
Data.Map.
map
:: (a -> b) -> Map k a -> Map k b# 与
GHC.Base.map
函数类似,但作用于每个键值对的值。exp15 = M.map (*100) $ M.fromList [(1, 1), (2, 4)] -- fromlist [(1,100),(2,400)]
-
Data.Map.
filter
:: (a -> Bool) -> Map k a -> Map k a# 与
GHC.List.filter
函数类似,但作用于每个键值对的值。exp16 = M.filter isUpper $ M.fromList [(1, 'a'), (2, 'A'), (3, 'b')] -- fromList [(2,'A')]
-
Data.Map.
toList
:: Map k a -> [(k, a)]# 将映射转换为序对列表。
exp17 = M.toList . M.insert 9 2 $ M.singleton 4 3 -- [(4,3),(9,2)]