# 序列函数
这些是遍历任何 `ISeq` 集合的高阶动词——列表、集合、映射、字符串和惰性序列皆然。`map`、`filter`、`take`、`drop` 和 `mapcat` 是按参数个数重载的:序列在前的形式返回惰性序列,而单参数形式返回为 `comp`、`transduce` 和 `into` 构建的转换器。其余函数是急切终止操作。语义见 惰性序列 和 转换器;本页是目录。所有函数都是标准库原生函数,无需导入即可使用。
## 函数
| 函数 | 用途 |
|---|---|
| `map xs f` / `map f` | 惰性序列 / 转换器 — 用 `f` 转换每个元素 |
| `filter xs pred?` / `filter pred?` | 惰性序列 / 转换器 — 保留 `pred?` 为真值的元素 |
| `take xs n` / `take n` | 惰性序列 / 转换器 — 前 `n` 个元素 |
| `drop xs n` / `drop n` | 惰性序列 / 转换器 — 除前 `n` 个之外的所有元素 |
| `mapcat xs f` / `mapcat f` | 惰性序列 / 转换器 — 应用 `f`,拼接结果 |
| `reduce xs init f` | 折叠值 — 用 `($acc $it)` 累积 |
| `each xs f` | `nil` — 产生副作用的遍历 |
| `find xs pred?` | 第一个匹配项,或 `nil` |
| `any? xs pred?` | 布尔值 — 任一元素匹配 |
| `all? xs pred?` | 布尔值 — 所有元素都匹配 |
| `collect lazy-seq` | 列表 — 具体化惰性序列 |
| `group xs f` | 映射 — 按键 `f` 分区 |
| `len xs` | 数字 — 集合长度,会具体化惰性序列 |
说明:
- 两种参数个数。 对于五个重载函数,将序列放在前面(`[map $xs f]`、`$xs |> map f` 或 `$xs(map f)`)返回惰性序列:在终止操作具体化它之前不会执行任何工作。单参数形式(`[map f]`、`[take n]`)返回转换器,可通过 `[into target xf source]` 或 `[transduce xf rf init source]` 跨来源复用。
- `reduce` 以 `($acc $it)` 调用 `f`;`each` 仅用于副作用并返回 `nil`;`map` 才是返回值的那一个。
- `find`、`any?` 和 `all?` 在第一个决定性元素处短路。`group` 返回从每个键到成员列表的映射——不保证布尔键的顺序。
- 惰性结果不能直接打印。终止操作(`collect`、`reduce`、`each`、`len`)以及在 `for`、`echo` 和 `set` 中的隐式具体化会强制完成遍历。
### 转换器动词
| 函数 | 用途 |
|---|---|
| `comp xf1 xf2 ...` | 从右到左组合转换器;`[comp]` 是恒等转换器 |
| `transduce xf rf init coll` | 通过转换器归约集合 |
| `into target xf coll` | 将转换后的元素合入向量、集合或映射 |
| `completing f ?cf` | 将双参数函数包装为 `%Reducer` |
| `reduced v` | 将值包装为 `%Reduced` 提前终止信号 |
| `reduced? v` | 当 `v` 是 `%Reduced` 包装时为真 |
| `unreduced v` | 解包 `%Reduced` 包装;对普通值幂等 |
`map`、`filter`、`take`、`drop` 和 `mapcat` 的单参数转换器形式可与 `comp` 组合,并通过 `transduce` 或 `into` 应用;转换器 完整介绍了协议和归约机制。
## 示例
# Lazy pipeline — only the first two even values are mapped @{ 1 2 3 4 5 6 } |> filter { ($it % 2) == 0 } |> map { ($it * 10) } |> take 2 |> collect # => @{ 20 40 } # The same functions as 1-arg transducers, composed and applied with into def xf [comp [map { ($it * 2) }] [filter { ($it > 3) }]] [into @{} $xf @{ 1 2 3 4 }] # => @{ 4 6 8 } # Eager terminals [reduce @{ 1 2 3 4 } 0 { ($acc + $it) }] # => 10 [find @{ 1 2 3 4 } { ($it > 2) }] # => 3 [any? @{ 1 2 3 } { ($it > 2) }] # => true [all? @{ 1 2 3 } { ($it > 0) }] # => true each @{ "a" "b" } { echo $it } # prints a, b; returns nil [group @{ 1 2 3 4 5 } { ($it % 2) == 0 }] # => %{ false @{1 3 5} true @{2 4} } [collect [map @{ 1 2 3 } { ($it * 2) }]] # => @{ 2 4 6 } [len [filter @{ 1 2 3 4 5 6 } { ($it % 2) == 0 }]] # => 3 [collect [mapcat @{ 1 2 3 } { @{ $it $it } }]] # => @{ 1 1 2 2 3 3 }