# 列表
列表是 Deft 的持久化不可变向量:字面量 `@{ ... }` 构建一个列表,
这里的每个操作都返回新列表,而不是修改原列表。这些裸函数被编译
进每个运行时,无需导入。转换动词(`map`、`filter`、`reduce` 等)
位于序列函数;关于集合模型的整体介绍,参见
集合。
## 函数
| 函数 | 用途 |
|---|---|
| `len xs` | 长度——适用于列表、映射、集合和字符串(码点) |
| `first xs`, `last xs` | 第一个 / 最后一个元素(空时为 `nil`) |
| `rest xs` | 除第一个元素外的所有元素 |
| `nth xs i` | 索引 `i` 处的元素;负数从末尾计数 |
| `slice xs start end` | 子列表或子字符串;`$xs(a..b)` 是语法糖 |
| `reverse xs` | 反转后的列表(或字符串) |
| `range end` / `range start end ?step` | 数值列表,从 `start`(含)到 `end`(不含) |
| `in? xs v` | 成员测试 |
| `append xs v` | 追加 `v` 后的新列表 |
| `flatten xs` | 将嵌套列表展平一层 |
| `sort xs` / `sort xs cmp` | 升序排序,或使用比较器 |
| `unique xs` | 去重,保留首次出现 |
| `take xs n`, `drop xs n` | 前 / 后 N 个元素(惰性) |
| `zip as bs` | 将两个列表配对 |
| `from-entries pairs` | 从 `@{ key value }` 对构建映射 |
| `set-nth xs i v`, `insert-nth xs i v`, `remove-nth xs i` | 索引操作 |
索引规则:`nth`、`slice`、`set-nth` 和 `remove-nth` 接受负索引
(从末尾计数)。越界的 `nth` 返回 `nil`;`set-nth` 和 `remove-nth`
返回原列表不变;`insert-nth` 将索引限制在 `[0, len]`。
给定集合时,`take` 和 `drop` 返回惰性序列;单参数形式 `[take n]`
和 `[drop n]` 返回转换器(参见
惰性序列和
转换器)。
`in?` 是普通函数,不是操作符——写成 `[in? $xs $v]`。不带比较器的
`sort` 使用值排序;带比较器时,比较器接收两个元素并返回布尔值。
要就地扩展局部列表,请使用 `$xs << $v`(`append` 的可变版本);
关于追加语义参见集合,关于何时优先
使用哪种形式参见
语法与风格。
## 示例
def xs @{ 10 20 30 } $xs(len) # => 3 $xs(first) # => 10 $xs(last) # => 30 $xs(rest) # => @{ 20 30 } $xs(nth 1) # => 20 $xs(1..3) # => @{ 20 30 } — range slice $xs(reverse) # => @{ 30 20 10 }
构造与结构变换:
[range 5] # => @{ 0 1 2 3 4 } [range 1 7 2] # => @{ 1 3 5 } — with step [append $xs 40] # => @{ 10 20 30 40 } [flatten @{ @{ 1 2 } @{ 3 4 } }] # => @{ 1 2 3 4 } [sort @{ 3 1 2 }] # => @{ 1 2 3 } [sort @{ 3 1 2 } {|a b| ($a > $b)}] # descending, comparator form [unique @{ 1 1 2 3 3 }] # => @{ 1 2 3 }
取用、丢弃、配对以及重建映射:
[take $xs 2] # => @{ 10 20 } [drop $xs 2] # => @{ 30 } [zip @{ :a :b } @{ 1 2 }] # => @{ @{ :a 1 } @{ :b 2 } } [from-entries [zip @{ :a :b } @{ 1 2 }]] # => %{ :a 1 :b 2 }
索引操作与成员测试返回新列表:
[set-nth $xs 0 99] # => @{ 99 20 30 } [insert-nth $xs 1 15] # => @{ 10 15 20 30 } [remove-nth $xs 1] # => @{ 10 30 } [in? $xs 20] # => true
用 `<<` 累积到局部变量(就地修改),或用 `append` 保持纯函数
形式:
def out @{} for x in @{ 1 2 3 } { $out << ($x * 2) } $out # => @{ 2 4 6 } [append $xs 99] # $xs is still @{ 10 20 30 }