F# Map
最后修改时间 2025 年 5 月 1 日
本文探讨了如何在 F# 中有效地使用 Map
集合。
在 F# 中,map 是一个不可变的键/值对集合,旨在实现高效的查找和数据关联。与列表或数组不同,Map 通过唯一的键提供对值的快速访问,使其成为结构化数据存储的理想选择。由于 Map 是不可变的,任何修改都会创建一个新的 Map 实例,而不是改变现有的实例,从而确保了数据的一致性和函数式纯粹性。
Map 会按排序顺序维护其键,从而提供可预测的迭代行为和优化的检索性能。它们通常用于关联数据结构,例如配置文件、查找表或需要快速基于键访问的结构化集合。
F# Map 简单示例
以下是一个简单的 Map 示例。
let words = Map [1, "book"; 2, "sky"; 3, "work"; 4, "cloud"] printfn "%A" words printfn "%s" words[1] printfn "%s" words[4]
我们有一个单词 Map。键是整数,值是字符串。
let words = Map [1, "book"; 2, "sky"; 3, "work"; 4, "cloud"]
键与值之间用逗号分隔。键值对之间用分号分隔。
printfn "%A" words
使用 %A
格式说明符,我们会美观地打印 Map。
printfn "%s" words[1] printfn "%s" words[4]
我们打印索引为 1 和 4 的元素。
λ dotnet fsi main.fsx map [(1, "book"); (2, "sky"); (3, "work"); (4, "cloud")] book cloud
F# Map 大小
Count
属性返回 Map 中键值对的数量。
let words = Map [1, "book"; 2, "sky"; 3, "work"; 4, "cloud"] let n = words.Count printfn $"The map has {n} elements"
该示例打印 Map 中元素的数量。
F# Map 迭代
在下一个示例中,我们将遍历 Map 的元素。
let words = Map [1, "book"; 2, "sky"; 3, "work"; 4, "cloud"] printfn "%A" words words |> Map.iter (fun k v -> printfn ($"{k}: {v}")) for key in words.Keys do printfn "%d" key for value in words.Values do printfn "%s" value for e in words do printfn $"{e.Key}: {e.Value}"
我们提供了两种基本的迭代方式:函数式和命令式。函数式使用 Map.iter
函数,而命令式使用 for 循环。
words |> Map.iter (fun k v -> printfn ($"{k}: {v}"))
Map.iter
是遍历 Map 元素的函数式方式。
for key in words.Keys do printfn "%d" key
我们遍历 Map 的键。
for value in words.Values do printfn "%s" value
我们遍历 Map 的值。
for e in words do printfn $"{e.Key}: {e.Value}"
我们遍历 Map 的键值对。
λ dotnet fsi main.fsx map [(1, "book"); (2, "sky"); (3, "work"); (4, "cloud")] 1: book 2: sky 3: work 4: cloud 1 2 3 4 book sky work cloud 1: book 2: sky 3: work 4: cloud
F# Map.filter
我们可以使用 Map.filter
过滤 Map 元素。
let words = Map [ 1, "book" 2, "sky" 3, "work" 4, "cloud" 5, "water" 6, "war" ] words |> Map.filter (fun _ v -> v.Contains "w") |> Map.values |> Seq.iter (printfn "%s")
在程序中,我们找出所有以 'w' 开头的值。
words |> Map.filter (fun _ v -> v.Contains "w") |> Map.values |> Seq.iter (printfn "%s")
我们将一个谓词 lambda 传递给 filter 方法;它检查值是否包含 'w'。结果被传递给 Map.values
来提取所有值。然后,这些值被迭代并打印到控制台。
λ dotnet fsi main.fsx work water war
F# Map Remove
Remove
方法返回一个已移除指定键值对的新 Map。
let words = Map [ 1, "book" 2, "sky" 3, "work" 4, "cloud" 5, "water" 6, "war" ] let res = words.Remove 1 printfn "%A" res printfn "%A" words
在示例中,我们删除了键为 1 的元素。原始 Map 未被更改。
λ dotnet fsi main.fsx map [(2, "sky"); (3, "work"); ... (6, "war")] map [(1, "book"); (2, "sky"); (3, "work"); ... (6, "war")]
F# Map Add
使用 Add
,我们向 Map 添加一个新元素。
let words = Map [ 1, "book" 2, "sky" 3, "work" 4, "cloud" 5, "water" 6, "war" ] let res = Map.add 7 "falcon" words printfn "%A" res printfn "%A" words
我们向 Map 添加了一个新的键值对。
λ dotnet fsi main.fsx map [(1, "book"); (2, "sky"); ... (6, "war"); (7, "falcon")] map [(1, "book"); (2, "sky"); ... (6, "war")]
F# Map.empty
我们可以使用 Map.empty
创建一个空的 Map,然后使用 Add
添加新元素。
type User = { Name: string Occupation: string } let users = Map.empty. Add(1, {Name="John Doe"; Occupation="gardener"}). Add(2, {Name="Roger Roe"; Occupation="driver"}). Add(3, {Name="Lucy Smith"; Occupation="teacher"}). Add(4, {Name="Tom Jones"; Occupation="programmer"}) users |> Map.iter (fun k v -> printfn $"{k}: {v}")
利用 Map.empty
,我们创建了一个用户 Map。
λ dotnet fsi main.fsx 1: { Name = "John Doe" Occupation = "gardener" } 2: { Name = "Roger Roe" Occupation = "driver" } 3: { Name = "Lucy Smith" Occupation = "teacher" } 4: { Name = "Tom Jones" Occupation = "programmer" }
F# Map 列表
在下一个示例中,我们定义了一个 Map 列表。
let fruits1 = Map [ "oranges", 2; "bananas", 3 ] let fruits2 = Map [ "plums", 4; "kiwis", 5 ] let all = [ Map[1, fruits1]; Map[2, fruits2] ] all |> List.iter (Map.iter (fun k v -> printfn $"{k} {v}")) printfn "-------------------" for nested in all do for e in nested do printfn $"{e.Key} {e.Value}"
我们定义了两个 Map,并将它们插入到一个列表中。然后以声明式和命令式方式迭代该列表。
all |> List.iter (Map.iter (fun k v -> printfn $"{k} {v}"))
我们使用 List.iter
和 Map.iter
以声明式方式迭代 Map 列表。
for nested in all do for e in nested do printfn $"{e.Key} {e.Value}"
命令式地,我们使用两个 for 循环遍历列表。
λ dotnet fsi main.fsx 1 map [(bananas, 3); (oranges, 2)] 2 map [(kiwis, 5); (plums, 4)] ------------------- 1 map [(bananas, 3); (oranges, 2)] 2 map [(kiwis, 5); (plums, 4)]
在本文中,我们学习了 F# 中的 Map。