Return variables and their matches in ets select

Leo-Nogismus
Fri, 31 May 2024 09:11:27 +0000
Questions / Help

I was wondering if there is a way to return both the variables (e.g., :“$1”), and its matched value with a single call to :ets.select(table, match_spec).

Assuming, for example, that we have an ets table called :foo, which is filled with entries of, for example, {:a, %{b: :c}}, and a match specification like [{{:a, %{b: :"$1"}, [], [something_here]}]. Is there a way to define some functions in the match specification’s body such that I get a map of “variable-atom” to “matched-value”, or similar?

So, for example:

iex(1)> :ets.new(:foo, [:bag, :public, :named_table])
iex(2)> :ets.insert(:foo, {:a, %{b: :c}})
iex(3)> :ets.select(:foo, [{{:a, %{b: :"$1"}}, [], [:"$1"]}])

returns

[:c]

but what I’m hoping to find is a way to have :ets.select return for this example

%{"$1": :c}

or anything like that.

I know that there is the match body variable :"$$" that returns a list of all the variables’ values. The issue is just that the match_spec is dynamically created, and I don’t know which variables (i.e., which integer numbers after the dollar sign) are in the match spec at the time of the select call. I need those to construct guards for a second select call.

Of course, this is a very small example. In my case, the terms stored in the ets table are much more complex, making it very hard to iterate over them to check for variable-value matches.

Any help would be appreciated.

4 posts - 3 participants