跳到主要内容

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 > 1
  • lambda 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 函数的返回类型转换为 BOOLlist_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 函数的返回类型转换为 BOOLlist_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