2 番目の要素で一致が見つかった場合はタプルから最初の要素を選択し、最初の要素が一致した場合は 2 番目の要素を選択する一致仕様を作成したいと考えています。ets:match を 2 回呼び出すのではなく、1 つの一致指定でこれを実行できますか?
2 に答える
はい。
ドキュメントにはis_integer(X), is_integer(Y), X + Y < 4711
、またはの例があり[{is_integer, '$1'}, {is_integer, '$2'}, {'<', {'+', '$1', '$2'}, 4711}]
ます。
使用している場合はfun2ms
、2 つの句で関数を書くだけです。
fun({X, Y}) when in_integer(X)
andalso X > 5 ->
Y;
({X, Y}) when is_integer(Y)
andalso Y > 5 ->
X.
ただし、2 つの を作成することもできますMatchFunctions
。それぞれの構成{MatchHead, [Guard], Return}
。
マッチ ヘッドは基本的に、データがどのように見えるか (タプルか、要素の数か...) を示し、各要素の一致変数$N
にN
数値を割り当てます。2要素のタプルを使用しているとしましょう。マッチヘッドは{'$1', '$2'}
.
次にガードを作成しましょう: 最初の関数では、最初の引数が 10 より大きい整数であるなど、単純なものを想定します。したがって、最初のガードは{is_integer, '$2'}
, 2 番目になり{'>', '$2', 5}
ます。両方で、マッチ ヘッドの最初の要素を使用します'$2'
。2 番目の一致関数には同じガードがありますが、'$1'
.
そして、いよいよ帰還。要素を 1 つだけ返したいので、最初の関数では'$1'
、2 番目の関数では になります'$2'
(追加の要素タプルでラップする必要があるため、タプルを返すのはもう少し複雑です)。
最後に、まとめると次のようになります
[ _FirstMatchFunction = {_Head1 = {'$1', '$2'},
_Guard1 = [{is_integer, '$2},
{'>', '$2', 5}], % second element matches
_Return1 = [ '$1']}, % return first element
_SecondMatchFunction = {_Head2 = {'$1', '$2'},
_Guard2 = [{is_integer, '$1},
{'>', '$1', 5}], % second element matches
_Return2 = [ '$2']} ] % return first element
Havent にはすべてをテストする時間がありすぎましたが、動作するはずです (おそらく微調整が必要です)。
-export([main/0]).
-include_lib("stdlib/include/ms_transform.hrl").
main() ->
ets:new(test, [named_table, set]),
ets:insert(test, {1, a, 3}),
ets:insert(test, {b, 2, false}),
ets:insert(test, {3, 3, true}),
ets:insert(test, {4, 4, "oops"}),
io:format("~p~n", [ets:fun2ms(fun({1, Y, _Z}) -> Y;
({X, 2, _Z}) -> X end)]),
ets:select(test, ets:fun2ms(fun({1, Y, _Z}) -> {first_match, Y};
({X, 2, _Z}) -> {second_match, X}
end)).
出力は次のとおりです。
[{{1,'$1','$2'},[],['$1']},{{'$1',2,'$2'},[],['$1']}]
[{first_match,a},{second_match,b}]