当你有了函数或原始值类型,你可能想知道如何处理它们的集合。Janet 有一些功能强大的核心数据结构。主要的6种内置数据类型是表,结构体,数组,元组,字符串和缓冲区。下表描述了它们之间的关系。
| Interface | Mutable | Immutable |
|---|---|---|
| Indexed | Array | Tuple |
| Dictionary | Table | Struct |
| Bytes | Buffer | String (Symbol, Keyword) |
可索引类型是线性链表,可以通过整数索引在常量时间复杂度内访问。为了快速访问,可索引类型底层使用了一整块内存,且索引从0开始。字典类型将值关联到键,它与索引类型的区别是键不止是整数。字典类型底层使用哈希表实现,同样提供常数时间复杂度的查询和插入(可变类型)。最后 "bytes" 抽象的是任何包含字节序列的类型。它有整数索引和整数值(0-255),因此它更像是数组和元组。字节序列不能包含非整数值。
下表显示了内置数据结构的各种操作的时间复杂度和其他信息。数据结构上的所有基本操作都会在常数时间内运行,无论数据结构中的项目数量有多少。
| Data Structure | Access | Insert/Append | Delete | Space Complexity | Mutable |
|---|---|---|---|---|---|
| Array * | O(1) | O(1) | O(1) | O(n) | Yes |
| Tuple | O(1) | - | - | O(n) | No |
| Table | O(1) | O(1) | O(1) | O(n) | Yes |
| Struct | O(1) | - | - | O(n) | No |
| Buffer | O(1) | O(1) | O(1) | O(n) | Yes |
| String/Keyword/Symbol | - | - | - | O(n) | No |
注意:数组的追加和删除对应的是 array/push 和 array/pop。随机删除和插入时间复杂度是 O(n), n 是数组中元素数量。
lisp
(def my-tuple (tuple 1 2 3))
(def my-array @(1 2 3))
(def my-array (array 1 2 3))
(def my-struct {
:key "value"
:key2 "another"
1 2
4 3})
(def another-struct
(struct :a 1 :b 2))
(def my-table @{
:a :b
:c :d
:A :qwerty})
(def another-table
(table 1 2 3 4))
(def my-buffer @"thisismutable")
(def my-buffer2 @``This is also mutable``)
读取数据结构中的值使用 get 或 in 函数。第一个参数是数据结构本身,第二个参数是键。可选的第三个参数是当值不存在时的默认值。
lisp
(get @{:a 1} :a) # -> 1
(get {:a 1} :a) # -> 1
(in {:a 1} :a) # -> 1
(get @[:a :b :c] 2) # -> :c
(in @[:a :b :c] 2) # -> :c
(get (tuple "a" "b" "c") 1) # -> "b"
(get @"hello, world" 1) # -> 101
(get "hello, world" 1) # -> 101
(in "hello, world" 1) # -> 101
(get {:a :b} :a) # -> :b
(get {:a :b} :c :d) # -> :d
(in {:a :b} :c :d) # -> :d
针对表和结构体的 in 函数(v1.5.0添加)和 get 一样。但是用于数组,元组和字符串类数据结构时,如果索引超出范围就会报错,如果需要检测这类错误,推荐使用 in。
lisp
(get @[:a :b :c] 3) # -> nil
(in @[:a :b :c] 3) # -> raises error
使用 put 函数可以修改可变数据结构。它接受3个参数,数据结构,键和值,并返回更新后的数据结构。允许的键和值类型取决于传递的数据结构。
lisp
(put @[] 100 :a)
(put @{} :key "value")
(put @"" 100 92)
注意,对于数组和缓冲区,如果写入的索引超过了数组的长度,它们会被扩容,并分别使用 nil 和 0 填充。
最后一个用于所有数据结构的通用函数是 length 函数。它返回数据结构中的元素数量(字典类型中键的数量)。