1

I'd like to know if there is a function in Erlang can help me know whether an element is in a tuple or not. Like sets:is_element/2.

Tuple = {aaa,bbb,ccc}.
is_element_of_tuple(Tuple, aaa)  % => true
is_element_of_tuple(Tuple, ddd)  % => false
halfelf
  • 9,737
  • 13
  • 54
  • 63

2 Answers2

6

You can always transform the tuple to a list using tuple_to_list/1:

is_element_of_tuple(Tuple, Element) ->
    lists:member(Element, tuple_to_list(Tuple)).
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
  • 2
    Arrays are indeed more suited for this. I'm to understand tuples were intended to be pattern matched and so you should almost always be using element(X, T) to find if an element is in a certain position of a tuple. – zetavolt Sep 04 '12 at 04:38
  • Why do you convert to list? Why not just using tuple_size/1 and recursive calls to element/2 to see whether the element is present or not? – rks Sep 04 '12 at 07:54
  • 6
    Using `lists:member/2` is probably better here. – rvirding Sep 04 '12 at 08:10
  • Could you show us the context in which you want to use this? I bet there's a better alternative which involves pattern matching. – Roberto Aloi Sep 04 '12 at 08:27
  • rvirding, of course! I've changed the answer. rks, because I think this is really easy to both read and implement. In addition tuples are usually small/bounded so the performance should not be terrible. Of course it is usually better to just use a list as a datastructure to begin with if you will need to check for membership later on. – Emil Vikström Sep 04 '12 at 16:49
4

The simple answer is: no there is no function to do this. You have to write your own loop which traverses all the elements of a tuple until it either finds or does not find it. You an either convert the tuple to a list as above or write your own loop, something like:

is_element_of_tuple(E, Tuple) ->
    is_element_of_tuple(E, Tuple, 1, tuple_size(Tuple)).

is_element_of_tuple(E, T, I, S) when I =< S ->
    case element(I, T) of
        E -> true;
        _ -> is_element_of_tuple(E, T, I+1, S)
    end;
is_element_of_tuple(_, _, _, _) -> false.                 %Done all the elements

Using a case and matching in this way means we check for exact equality, and it is probably a little faster than using =:= and checking if that returns true or false.

rvirding
  • 20,848
  • 2
  • 37
  • 56
  • 1
    This throws a `function_clause` error if the value is not present, since in the last clause the third argument will be one more than the fourth. – legoscia Sep 04 '12 at 11:19