(Elixir/Erlang) :ets.select_count returns 0

70 views Asked by At

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:

  • erlang - 25.3.2.5
  • elixir - 1.15.4 (I took versions from package manager, tell me if it's wrong way)

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
1

There are 1 answers

1
Peaceful James On BEST ANSWER

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.