来自Erlang list-comprehension的意外空列表

时间:2016-03-29 07:33:26

标签: erlang list-comprehension

我使用list comprehension将数据库行从元组列表转换为映射列表。有一天,我在我的数据库表中添加了一些新列,忘了在任何地方更改代码。 因此我发现了一个奇怪的效果:数据库行变成一个空列表。

erl控制台中的代码示例:

> DbRows = [{1, 1, 1}, {2, 2, 2}].
[{1,1,1},{2,2,2}]
> [#{<<"col1">> => Col1, <<"col2">> => Col2} ||{Col1, Col2} <- DbRows].
[]

为什么Erlang在这种情况下不会生成异常错误:右侧值不匹配

此代码是否正常,或者首选其他语法来执行此类数据转换?

2 个答案:

答案 0 :(得分:5)

Erlang不会生成任何异常,因为它是正确的语法。生成器{Col1, Col2} <- DbRows同时是一个过滤器。因此,任何与模式不匹配的元素都会被跳过。 在你的情况下,我会做这样的事情:

-define(FIELDS, [id, some1, some2]).
DbRows = [{1, 1, 1}, {2, 2, 2}].
Prepare = fun(X) ->
    maps:from_list(lists:zip(?FIELDS, tuple_to_list(X)))
end.
[ Prepare(Row) || Row <- DbRows].

当您添加新字段时,您需要在宏中添加该字段。

答案 1 :(得分:1)

我不喜欢这个“功能”,因为根据我的经验,它往往会掩盖错误,但是nikit的答案对于你看到的结果的原因是正确的。

您可以通过将模式匹配移动到列表推导的左侧来获取异常:

[ case Row of {Col1, Col2} -> #{<<"col1">> => Col1, <<"col2">> => Col2} || Row <- DbRows ]