2013-02-25 29 views
0

我有以下代碼從具有值等於Accountnumber的字段的記錄列表中返回記錄。使用過濾器的Erlang記錄處理

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) 

什麼錯誤原因?

+0

雖然它可能是誘人重寫像上面使用像圖公知的功能的一個遞歸函數,摺疊和過濾器,請記住,'filter'會發現* *所有匹配的元素,這意味着它總是搜索整個列表。 (這也意味着它可以返回多個命中,而不僅僅是第一個!) – 2013-02-27 17:17:52

回答

6

有代碼

1.過濾器應始終返回原子true或false所有列表元素多的問題。這會導致你的錯誤。

2.當樂趣塊外的變量用於樂趣頭時,它們沒有圖案匹配,外面的變量被遮罩。因此模式匹配失敗。

您可以在下面看到修改的代碼。

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

爲了表現得像上面的'lookup'函數,你需要對'filter'的結果進行判斷,看看它是否返回空列表( 'not_found')或列表'[Req]'。現在它在成功時返回'[Req]',在失敗時返回'[]'。您還需要考慮到存在多個具有相同編號的帳戶的可能性。 – 2013-02-27 17:19:25