0

Is there any way to retrieve an element from an ETS table and acces, say column 1, without inserting the object into the ETS as a record?

The only place I have seen similar syntax, to refer to each column is with the '$1' on the match arguments.

intrigued_66
  • 16,082
  • 51
  • 118
  • 189
  • 1
    Elements of an ets table are not strictly records but tuples of size greater than 1. So you may access [specific elements on lookup](http://erldocs.com/R14B02/stdlib/ets.html?i=2&search=#lookup_element/3) if you wish to. – Keynslug Mar 21 '12 at 11:57

2 Answers2

3

Assuming you have the following:

1> ets:new(people, [set, named_table]).
2> ets:insert(people, {silvio, italy, joker}).
3> ets:insert(people, {roberto, italy, employee}).

(Note I'm adding a generic tuple to the table - a record is simply a tuple where the first element is the name of the record itself and you have some syntactic sugar to access the records' elements -)

You could do the following 'match' operation:

4> ets:match(people, {'$1', 'italy', '_'}).

Which means:

Match all entries made of three columns, where the second element is the atom 'italy'. Discard the third argument, since I'm only interested into the first one.

This would return:

[[silvio],[roberto]]

Alternatively, you could perform the following 'select' operation:

5> ets:select(people, [{{'$1', '$2', '$3'},
                       [{'==', '$2', italy}],
                       [['$3']]}]).

Which means:

Select on all the entries made of three 'columns', where the second element is equal to 'italy', returning the third element only.

In your case, that would return:

[[joker],[employee]]

Bare in mind that the match operations, to be really efficient, have been implemented as BIFs, so they will stop other processes while executing. This means that, for large table, you should look at other mechanisms, such as "traversing an ETS table".

halfer
  • 19,824
  • 17
  • 99
  • 186
Roberto Aloi
  • 30,570
  • 21
  • 75
  • 112
1

ets:lookup_element is quite efficient for retrieving a single column (as opposed to retrieving the whole record with ets:lookup), especially if you have long records (tuples) in the table.

Edit: And if you want to update a certain column of a record without having to reinsert the whole tuple, you can use ets:update_element/3. (Actually the question might be just about that, it's not completely clear to me. Anyhow, now both cases are answered :))

In addition, if the update is about incrementing a counter, use ets:update_counter/3. This is atomic, so you don't have to do the lookup-increment-update (non-atomic) sequence.

tzp
  • 544
  • 7
  • 10