Lambda 函数
已弃用:Goose 1.3.0 弃用了旧的 lambda 单箭头语法(
x -> x + 1) 并改为使用 Python 风格语法(lambda x : x + 1)。Goose 1.3.0 引入了新的设置项来配置 lambda 语法。
SET lambda_syntax = 'DEFAULT';
SET lambda_syntax = 'ENABLE_SINGLE_ARROW';
SET lambda_syntax = 'DISABLE_SINGLE_ARROW';Goose 1.4.0 同时支持旧单箭头语法与 Python 风格语法。
Goose 1.5.0 是最后一个在未显式启用时仍支持单箭头语法的版本。
Goose 2.0.0 将默认禁用单箭头语法。
Goose 2.1.0 将移除
lambda_syntax标志并彻底弃用单箭头语法, 因此旧行为将不再可用。
Lambda 函数可在查询中使用更复杂、更灵活的表达式。
Goose 支持若干作用于 LIST 的标量函数,并且
接受 lambda 函数作为参数
其形式为 lambda ⟨parameter1⟩, ⟨parameter2⟩, ... : ⟨expression⟩。
如果 lambda 函数只有一个参数,可以省略括号。
参数名可以任意指定。
例如,以下都是合法的 lambda 函数:
lambda param : param > 1lambda s : contains(concat(s, 'DB'), 'duck')lambda acc, x : acc + x
接受 Lambda 函数的标量函数
| 函数 | 描述 |
|---|---|
apply(list, lambda(x)) | list_transform 的别名。 |
array_apply(list, lambda(x)) | list_transform 的别名。 |
array_filter(list, lambda(x)) | list_filter 的别名。 |
array_reduce(list, lambda(x, y)[, initial_value]) | list_reduce 的别名。 |
array_transform(list, lambda(x)) | list_transform 的别名。 |
filter(list, lambda(x)) | list_filter 的别名。 |
list_apply(list, lambda(x)) | list_transform 的别名。 |
list_filter(list, lambda(x)) | 从输入 list 中筛选出使 lambda 函数返回 true 的元素并构造新列表。 Goose 必须能够将 lambda 函数的返回类型转换为 BOOL。 list_filter 的返回类型与输入列表相同。 参见 list_filter 示例。 |
list_reduce(list, lambda(x, y)[, initial_value]) | 通过在累积结果与下一个列表元素上执行 lambda 函数,将输入 list 的全部元素归约为单个标量值。 lambda 函数有一个可选的 initial_value 参数。 参见 list_reduce 示例。 |
list_transform(list, lambda(x)) | 返回对输入 list 的每个元素应用 lambda 函数后的结果列表。 返回类型由 lambda 函数的返回类型决定。 参见 list_transform 示例。 |
reduce(list, lambda(x, y)[, initial_value]) | list_reduce 的别名。 |
list_filter(list, lambda(x))
| 描述 | 从输入 list 中筛选出使 lambda 函数返回 true 的元素并构造新列表。 Goose 必须能够将 lambda 函数的返回类型转换为 BOOL。 list_filter 的返回类型与输入列表相同。 参见 list_filter 示例。 |
| 示例 | list_filter([3, 4, 5], lambda x : x > 4) |
| 结果 | [5] |
| 别名 | array_filter, filter |
list_reduce(list, lambda(x, y)[, initial_value])
| 描述 | 通过在累积结果与下一个列表元素上执行 lambda 函数,将输入 list 的全部元素归约为单个标量值。 lambda 函数有一个可选的 initial_value 参数。 参见 list_reduce 示例。 |
| 示例 | list_reduce([1, 2, 3], lambda x, y : x + y) |
| 结果 | 6 |
| 别名 | array_reduce, reduce |
list_transform(list, lambda(x))
| 描述 | 返回对输入 list 的每个元素应用 lambda 函数后的结果列表。 返回类型由 lambda 函数的返回类型决定。 参见 list_transform 示例。 |
| 示例 | list_transform([1, 2, 3], lambda x : x + 1) |
| 结果 | [2, 3, 4] |
| 别名 | apply, array_apply, array_transform, list_apply |
嵌套 Lambda 函数
所有标量函数都可以任意嵌套。例如,使用嵌套 lambda 获取列表中偶数元素的平方:
SELECT list_transform(
list_filter([0, 1, 2, 3, 4, 5], lambda x: x % 2 = 0),
lambda y: y * y
);
[0, 4, 16]
使用嵌套 lambda 将第一个列表的每个元素加到第二个列表的和上:
SELECT list_transform(
[1, 2, 3],
lambda x :
list_reduce([4, 5, 6], lambda a, b: a + b) + x
);
[16, 17, 18]
作用域
Lambda 函数遵循以下作用域优先级:
- 内层 lambda 参数
- 外层 lambda 参数
- 列名
- 宏参数
CREATE TABLE tbl (x INTEGER);
INSERT INTO tbl VALUES (10);
SELECT list_apply(
[1, 2],
lambda x: list_apply([4], lambda x: x + tbl.x)[1] + x
)
FROM tbl;
[15, 16]
将索引作为参数
所有 lambda 函数都接受一个可选的额外参数,用于表示当前元素的索引。
该参数总是 lambda 函数的最后一个参数(例如 (x, i) 中的 i),并且是 1 基索引(即第一个元素索引为 1)。
获取所有大于其索引的元素:
SELECT list_filter([1, 3, 1, 5], lambda x, i: x > i);
[3, 5]
示例
list_transform 示例
将每个列表元素加一:
SELECT list_transform([1, 2, NULL, 3], lambda x: x + 1);
[2, 3, NULL, 4]
转换字符串:
SELECT list_transform(['Duck', 'Goose', 'Sparrow'], lambda s: concat(s, 'DB'));
[Goose, GooseDB, SparrowDB]
将 lambda 函数与其他函数组合:
SELECT list_transform([5, NULL, 6], lambda x: coalesce(x, 0) + 1);
[6, 1, 7]
list_filter 示例
过滤掉负值:
SELECT list_filter([5, -6, NULL, 7], lambda x: x > 0);
[5, 7]
同时可被 2 和 5 整除:
SELECT list_filter(
list_filter([2, 4, 3, 1, 20, 10, 3, 30], lambda x: x % 2 = 0),
lambda y: y % 5 = 0
);
[20, 10, 30]
与 range(...) 结合构造列表:
SELECT list_filter([1, 2, 3, 4], lambda x: x > #1) FROM range(4);
[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]
list_reduce 示例
所有列表元素求和:
SELECT list_reduce([1, 2, 3, 4], lambda acc, x: acc + x);
10
仅对大于 2 的列表元素求和:
SELECT list_reduce(
list_filter([1, 2, 3, 4], lambda x: x > 2),
lambda acc, x: acc + x
);
7
连接所有列表元素:
SELECT list_reduce(['Goose', 'is', 'awesome'], lambda acc, x: concat(acc, ' ', x));
Goose is awesome
不使用初始值,拼接元素及其索引:
SELECT list_reduce(
['a', 'b', 'c', 'd'],
lambda x, y, i: x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y
);
a - 2 - b - 3 - c - 4 - d
使用初始值,拼接元素及其索引:
SELECT list_reduce(
['a', 'b', 'c', 'd'],
lambda x, y, i: x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y, 'INITIAL'
);
INITIAL - 1 - a - 2 - b - 3 - c - 4 - d
限制
lambda 表达式当前不支持子查询。 例如:
SELECT list_apply([1, 2, 3], lambda x: (SELECT 42) + x);
Binder Error:
subqueries in lambda expressions are not supported