集合和列表
你可能会发现自己拥有特定类型的多段数据。 你可以为每段数据创建变量,也可以将它们分组到集合中。 对数据进行分组可以带来好处,例如,这使你不仅能够对各段数据执行方法,还可以对作为一个整体的集合执行方法。
集合
需要使用集合的第一个标志是有多个数据片段,它们似乎具有相同的数据类型。 你可能会遇到有许多条目的情况,如下面的代码中所示:
let logEntryMonday = "first entry"
let logEntryTuesDay = "second entry"
let logEntryWednesday = "third entry"
在此代码中,你可以继续一个接一个地添加类似的条目,但在某些时候,这种方法会开始显得不切实际。 这些单独的条目不仅是相关的,而且实际上还是同一类型的。 那么为每个条目创建一个新变量是个好主意吗? 很有可能并非如此。 相反,请考虑改为使用集合,通过集合,你可以创建可管理的逻辑分组,无论是添加或删除数据还是使用其他操作:
logEntriesWeek = ["first entry"; "second entry"; "third entry"]
此代码要求进行的输入更少,而且还创建了一种顺序感,这样一来,所有相关的内容就能组合在一起了。
那么,F# 能为你提供什么呢? 首先,它可以提供三种类型的集合,每一种类型的集合都是针对特定情况设计的。
列表:F# 中的列表是有序、不可变、类型相同的元素集。 不可变意味着列表的性能可能优于数组,但是如果要更改列表内容,你可能需要一点创造性。 例如,你可能想根据现有列表创建一个新的列表。 本单元重点介绍如何使用列表。
数组:数组是固定大小的可变集合,其中包含相同类型的数据元素,采用从零开始的索引连续排序。 可变意味着可以轻松添加和删除数据元素,但性能可能会有所降低。
序列:序列是类型相同的元素的逻辑序列。 序列可以做出实时感受,因为它可以很好地处理大型数据集合,无需使用所有元素。 此外,它仅在需要时才计算元素。 因此,在某些情况下,序列可以提供优于列表的性能。
列表
如前所述,列表是有序且不可变的元素集。 下面是创建列表的一些方法:
let cards = ["Ace"; "King"; "Queen"]
在此代码中,将元素括在括号 ([]
) 中以定义列表。 列表项由分号 (;
) 分隔。
创建列表的另一种方式是将每个元素放在新行上,如下所示。 借助此方法,也无需使用分号了。
let cards = [
"Ace"
"King"
"Queen"
]
在列表中,元素的类型必须相同,因此不允许使用以下声明:
let cards = [ 1; "Ace"; "King" ] // not permitted
在此代码中,由于声明混合了数字和字符串,因此不允许使用此声明。 创建列表的另一种方式是使用范围运算符 (..
)。 目的是指定开头和结尾元素,用范围运算符 (..
) 分隔。 此操作将创建从头到尾的所有数字,包括中间的元素。 例如,可以使用以下代码创建数字 1 2 3 4 5
:
let numbers = [ 1 .. 5 ]
更改列表
如前所述,列表是不可变的,这意味着它们不能更改。 但是,换种方式思考,你可以使更改看起来像是向列表添加项,或甚至是向列表添加项列表。 这是什么意思? 请考虑以下示例:
let cards = ["Ace"; "King"; "Queen"]
前面的代码是一个由三个字符串组成的列表。 通过使用双冒号 (::
) 运算符,可以将项追加到列表开头。 结果是一个新列表,而旧列表不会受影响:
let cards = ["Ace"; "King"; "Queen"]
let newList = "Jack" :: cards // "Jack", "Ace", "King", "Queen"
还可以使用 @
运算符添加整个列表,如下所示:
let cards = ["Ace"; "King"; "Queen"]
let otherCardList = ["Jack"; "10"]
let fullList = cards @ otherCardList // "Ace", "King", "Queen", "Jack", "10"
列表模块中有一个 append()
函数,它适用于数组和序列集合。 例如,如果需要将集合类型从列表切换到序列,或者如果不想学习添加项的新方法,则最好使用 append()
。 使用 @
符号将元素添加到列表仅适用于列表结构。 现在再次查看这两个示例,但改为使用 append()
:
let cards = ["Ace"; "King"; "Queen"]
let otherCardList = ["10"; "9"]
let fullList = cards |> List.append ["Jack"] // "Jack", "Ace", "King", "Queen"
let fullList = cards |> List.append otherCardList // "10", "9", "Ace", "King", "Queen"
属性
F# 中的列表是作为链接列表实现的。 也就是说,列表是一个结构,其中每个元素都连接到另一个元素。 要了解的其他术语有“头”(列表中的第一个元素)和“尾”(包含不在头中的元素)。 例如,在列表 1 2 3 4
中,头为 1
,尾为 2 3 4
。
通过这种方式分隔元素,可以快速访问第一个元素,使你能够对它执行读取、删除或其他操作。 若要访问列表中任何特定的项,可以使用 Item
属性,该属性接受从零开始的索引,如下所示:
let list = [1; 2; 3; 4]
list.Item 1 // 2
下表对列表属性进行了介绍:
属性 | 说明 |
---|---|
头 | 列表中的第一个元素 |
空 | 返回一个空列表,可以在想要创建空列表时使用 |
IsEmpty | 检查当前列表是否为空 |
项目 | 检索指定位置(从零开始的索引)的当前元素 |
长度 | 返回列表中的项数 |
Tail | 返回列表中除第一个元素之外的所有元素 |