🎓 A1Learner
🔍
0 of 46 lessons completed

Elixir ETS Match Specs

A match specification is a small list of tuples that tells :ets.select which rows to return. Each entry holds a pattern, a list of guard tests, and a list of values to return.

Keep only rows over 18

Select names from rows whose second item is over 18, then sort the names.

table = :ets.new(:scores, [:set, :public])
:ets.insert(table, {"ana", 20})
:ets.insert(table, {"bo", 15})
:ets.insert(table, {"cy", 22})
IO.inspect(Enum.sort(:ets.select(table, [{{:"$1", :"$2"}, [{:>, :"$2", 18}], [:"$1"]}])) )

Match one exact age

Change the guard to an equality test and select the matching name.

table = :ets.new(:scores, [:set, :public])
:ets.insert(table, {"ana", 20})
:ets.insert(table, {"bo", 15})
:ets.insert(table, {"cy", 22})
IO.inspect(Enum.sort(:ets.select(table, [{{:"$1", :"$2"}, [{:==, :"$2", 20}], [:"$1"]}])) )

Return ages for every row

An empty guard list matches every row, and the result list picks the age from each row.

table = :ets.new(:scores, [:set, :public])
:ets.insert(table, {"ana", 20})
:ets.insert(table, {"bo", 15})
:ets.insert(table, {"cy", 22})
IO.inspect(Enum.sort(:ets.select(table, [{{:"$1", :"$2"}, [], [:"$2"]}])) )

Example

table = :ets.new(:scores, [:set, :public])
:ets.insert(table, {"ana", 20})
:ets.insert(table, {"bo", 15})
:ets.insert(table, {"cy", 22})
:ets.insert(table, {"dan", 18})
adults = Enum.sort(:ets.select(table, [{{:"$1", :"$2"}, [{:>, :"$2", 18}], [:"$1"]}]))
IO.inspect(adults)
IO.puts("count: #{length(adults)}")

Key points

  • Pattern: The pattern describes a row, with :"$1" standing for the first item and :"$2" for the second item.
  • Guard: The guard list holds tests that a row must pass, such as checking that an age is over 18.
  • Result: The result list holds the values to return for each row that passes.
  • Match all: An empty guard list matches every row in the table.
  • Hand-written specs: Match specifications in this course are written by hand as tuples.

In this example, four rows are inserted into a set table. A match specification keeps only rows whose age is over 18 and returns their names. The sorted names are printed, and the count is 2 because the row aged 18 does not pass.

Note

Sort the result when order matters, because :ets.select does not promise an order for a set table.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

In a match specification, what does the guard [{:>, :"$2", 18}] do?