erlangelixirets

(Elixir/Erlang) :ets.select_count returns 0


I'm writing a program using Elixir and I have a very strange error.

I have a table, which contains some values stored like that: {a, b}. A is unique value, b can be repeated.

I want to count how many rows I have, which have specific second value.

When I call

:ets.select_count(table, [{{:'$1', "a"}, [], [:'$1']}])

it returns 0, but if I call

length(:ets.select(table, [{{:'$1', "a"}, [], [:'$1']}]))

it returns expected result.

Table can't be changed between these two calls.

Versions:

I tried to find answer in google, I found nothing.

What am I doing wrong?

To reproduce:

table = :ets.new(:tbl, [])
:ets.insert(table, {"a", "b"})
:ets.insert(table, {"b", "a"})
IO.puts('select_count: #{:ets.select_count(table, [{{:'$1', "a"}, [], [:'$1']}])}') # prints 0
IO.puts('length(select): #{length(:ets.select(table, [{{:'$1', "a"}, [], [:'$1']}]))}') # prints 1

Solution

  • According to the Erlang docs:

    https://www.erlang.org/doc/man/ets#select_count-2

    This function can be described as a select_delete/2 function that does not delete any elements, but only counts them.

    So look at the docs for select_delete/2:

    https://www.erlang.org/doc/man/ets#select_delete-2

    The match specification has to return the atom true if the object is to be deleted. No other return value gets the object deleted.

    So you need to do this:

    :ets.select_count(table, [{{:'$1', "a"}, [], [true]}])
    

    Note the return value is true, to accord with the quote above.