1

例えば:

Db = [{pid1, {key1, {apple}}}, {pid1, {key2, {banana}}}, {pid1, {key3, {watermelon}}}, {pid2, {key1, {cucumber}}}, {pid2, {key2, {carrot}}}].

Pid = pid1、Key = key1 のタプルを返すことができます。これは {pid1, {key1, {apple}}} になります。どうすればこれを行うことができますか?BIF リストに似たもの:keyfind/3。

4

3 に答える 3

1

このようなルックアップを実行するにはいくつかの方法があり、最適な方法はありません。それは主にスタイルの問題です

  • @Emil Vikströmで提案されているように、結果が一致するとすぐに戻る再帰関数を作成できます。利点は、すべての要素を調べなくても、結果が見つかるとすぐにルックアップが返されることです。ただし、リストがそのような最適化を正当化するのに十分な長さである場合、別のデータ構造がより適切である可能性があると主張することができます (ソートされたリストやツリーなど)。lists:keyfind/3

  • @Pascal の提案どおりにlists:filter/2使用できます。これには、コードのメンテナンスに常に適したライブラリ関数に基づく再帰関数よりも利点があります。

  • リスト内包表記内でフィルターを使用できます。これはlists:filter/2アプローチと似ていますが、少し短くなっています。特にテストが非常に短い場合、リスト内包表記はlists:map/2andを使用するよりも Erlang に似ていると多くの人が考えています。lists:filter/2

    [T || {Pid, {Key, _Value}} = T <- Db, Pid =:= MyPid, Key =:= MyKey].

    key1 と pid1 が定数の場合、次のように書くこともできます。

    [T || {pid1, {key1, _Value}} = T <- Db].

于 2013-10-16T09:06:43.620 に答える
1

lists: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}}}]
于 2013-10-16T08:44:49.650 に答える
0

値を見つけたときに早期にブレークしたい場合は、パターン マッチングを使用して自分で実装できます。

pidkeyfind(_Pid, _Key, []) -> false;
pidkeyfind(Pid, Key, [Head = {Pid, {Key, _}} | _Tail]) -> Head;
pidkeyfind(Pid, Key, [_|Tail]) -> pidkeyfind(Pid, Key, Tail).
于 2013-10-16T08:48:09.360 に答える