使用过滤器的Erlang记录处理

使用过滤器的Erlang记录处理,erlang,record,Erlang,Record,我使用下面的代码从记录列表中返回一条记录,该记录的字段值等于Accountnumber lookup(AccountNumber, [#account{no=AccountNumber} = Rec | _]) -> Rec; lookup(AccountNumber, [_| T]) -> lookup(AccountNumber, T); lookup(AccountNumber, []) -> not_found. 上面的代码工作正常,但当我尝试

我使用下面的代码从记录列表中返回一条记录,该记录的字段值等于Accountnumber

lookup(AccountNumber, [#account{no=AccountNumber} = Rec | _]) ->
    Rec;
lookup(AccountNumber, [_| T]) ->
    lookup(AccountNumber, T);
lookup(AccountNumber, []) ->
    not_found.
上面的代码工作正常,但当我尝试使用以下代码将其转换为过滤器时:

lookup(AccountNumber, DBRef) ->
    lists:filter(fun(#account{no=AccountNumber} = Rec) -> Rec end, DBRef).
我得到了以下错误:

** exception error: no case clause matching #account{no = 2,balance = 0,pin = undefined,name = "Ali",
                                                 transactions = []}
   in function  lists:'-filter/2-lc$^0/1-0-'/2 (lists.erl, line 1271)

错误的原因是什么?

代码中存在多个问题

1.过滤器应始终为所有列表元素返回atom true或false。这是导致错误的原因

2.当fun块外部的变量用于fun头中时,它们没有模式匹配,外部的变量被屏蔽。因此,模式匹配失败

您可以在下面看到修改后的代码

  lookup(AccountNumber, DBRef)  ->
    lists:filter(
      fun(#account{no=AccNo}) when AccNo =:= AccountNumber -> true;
         (_) -> false 
      end, DBRef).

代码中存在多个问题

1.过滤器应始终为所有列表元素返回atom true或false。这是导致错误的原因

2.当fun块外部的变量用于fun头中时,它们没有模式匹配,外部的变量被屏蔽。因此,模式匹配失败

您可以在下面看到修改后的代码

  lookup(AccountNumber, DBRef)  ->
    lists:filter(
      fun(#account{no=AccNo}) when AccNo =:= AccountNumber -> true;
         (_) -> false 
      end, DBRef).

尽管使用map、fold和filter等著名函数重写上述递归函数很有诱惑力,但请记住
filter
将找到所有匹配的元素,这意味着它总是搜索整个列表。(这也意味着它可以返回多个点击,而不仅仅是第一个!)尽管使用诸如map、fold和filter之类的著名函数重写上面的递归函数可能很有诱惑力,但请记住,
filter
将找到所有匹配的元素,这意味着它总是搜索整个列表。(这也意味着它可以返回多个点击,而不仅仅是第一个!)为了像上面的
查找
函数一样工作,您需要对
筛选
的结果进行大小写,以查看它是返回空列表(
未找到
)还是返回列表
[Req]
。现在,它在成功时返回
[Req]
,在失败时返回
[]
。您还需要考虑存在多个具有相同编号的帐户的可能性。为了像上面的
查找
功能一样工作,您需要对
筛选
的结果进行分类,以查看它是否返回空列表(
未找到
)或列表中的一个值
[Req]
。现在,它在成功时返回
[Req]
,在失败时返回
[]
。您还需要考虑存在多个具有相同编号的帐户的可能性。