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
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.