例如:找到一個元組與兩個鍵
Db = [{pid1, {key1, {apple}}}, {pid1, {key2, {banana}}}, {pid1, {key3, {watermelon}}}, {pid2, {key1, {cucumber}}}, {pid2, {key2, {carrot}}}].
如果能夠返回的元組其中pid = PID1和密鑰= key1的,這將是{PID1,{鍵,{蘋果}}}。我會如何去做這件事?類似於BIF列表:keyfind/3。
例如:找到一個元組與兩個鍵
Db = [{pid1, {key1, {apple}}}, {pid1, {key2, {banana}}}, {pid1, {key3, {watermelon}}}, {pid2, {key1, {cucumber}}}, {pid2, {key2, {carrot}}}].
如果能夠返回的元組其中pid = PID1和密鑰= key1的,這將是{PID1,{鍵,{蘋果}}}。我會如何去做這件事?類似於BIF列表:keyfind/3。
如果你想,當你發現的價值,打破早,您也可以自己使用模式匹配實現它:
pidkeyfind(_Pid, _Key, []) -> false;
pidkeyfind(Pid, Key, [Head = {Pid, {Key, _}} | _Tail]) -> Head;
pidkeyfind(Pid, Key, [_|Tail]) -> pidkeyfind(Pid, Key, Tail).
與列表:filter/2它應該工作,這裏是一個如何使用它的例子。
1> Db = [{pid1, {key1, {apple}}}, {pid1, {key2, {banana}}}, {pid1, {key3, {watermelon}}}, {pid2, {key1, {cucumber}}}, {pid2, {key2, {carrot}}}].
[{pid1,{key1,{apple}}},
{pid1,{key2,{banana}}},
{pid1,{key3,{watermelon}}},
{pid2,{key1,{cucumber}}},
{pid2,{key2,{carrot}}}]
2> Find = fun (K1,K2,L) -> lists:filter(fun({X,{Y,_}}) -> X =:= K1 andalso Y =:= K2 end,L) end.
#Fun<erl_eval.18.82930912>
3> Find(pid1,key1,Db).
[{pid1,{key1,{apple}}}]
有幾種方法來進行這樣的查詢,並沒有最好的方法。這主要是,這與風格有關。
你可以寫一個遞歸函數將由@Emil Vikström只要結果一致返回,因爲suggested。優點是你不會瀏覽所有元素,但只要找到結果,查找就會返回,類似於lists:keyfind/3
所做的。然而,有人可能會爭辯說,如果列表足夠長以證明這樣的優化,另一個數據結構可能更合適(如排序列表或樹)。
您可以使用lists:filter/2
作爲suggested by @Pascal。這比基於庫函數的遞歸函數具有優勢,這對於代碼維護來說總是有利的。
您可以使用列表理解內的過濾器。這與lists:filter/2
方法相似,但稍短一些。許多人認爲列表理解比使用lists:map/2
和lists:filter/2
更像Erlang,特別是當測試如此之短時。
[T || {Pid, {Key, _Value}} = T <- Db, Pid =:= MyPid, Key =:= MyKey].
如果key1的和PID1是常數,你甚至可以寫:
[T || {pid1, {key1, _Value}} = T <- Db].
這個作品,更說教,但假設有至多1個記錄中匹配請求,如果是這樣的話,它的平均速度應該更快。 – Pascal
Pascal的確如此。我選擇了這種解釋(單擊),因爲這是list:keyfind/3的工作方式。 –