集合和列表

已完成

你可能会发现自己拥有特定类型的多段数据。 你可以为每段数据创建变量,也可以将它们分组到集合中。 对数据进行分组可以带来好处,例如,这使你不仅能够对各段数据执行方法,还可以对作为一个整体的集合执行方法。

集合

需要使用集合的第一个标志是有多个数据片段,它们似乎具有相同的数据类型。 你可能会遇到有许多条目的情况,如下面的代码中所示:

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 返回列表中除第一个元素之外的所有元素