例如:找到一个元组与两个键
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的工作方式。 –