Elixir generate inverted / reversed map I would like to transform the input
elems = [a, b, c]
terms = [t1, t2]

@spec contains?(term, elem) :: boolean
def contains?(term, elem), do: #implementation

to either of
%{t1 =&gt; [a, b], t2 =&gt; [c]}

or
%{t1 =&gt; [a], t2 =&gt; [b, c]}

where
t1 |&gt; contains?(a) #=&gt; true
t1 |&gt; contains?(b) #=&gt; true
t1 |&gt; contains?(c) #=&gt; false

t2 |&gt; contains?(a) #=&gt; false
t2 |&gt; contains?(b) #=&gt; true
t2 |&gt; contains?(c) #=&gt; true


My current solution is as follows
defmodule Test do
  def contains?(term, elem) do
    elem in term
  end

  def test do
    elems = [1,2,3]
    terms = [[1,2], [2,3]]
  
    elems
    |&gt; Enum.into(%{}, fn elem -&gt;
      {elem,
       terms |&gt; Enum.find(&amp;contains?(&amp;1, elem))}
    end)
    |&gt; reverse_map()
  end

  defp reverse_map(map, reversed \\ %{})
  defp reverse_map(map, reversed) when map_size(map) == 0, do: reversed

  defp reverse_map(map, reversed) do
    [key | _] = Map.keys(map)
    {value, map} = Map.pop!(map, key)
    reversed = Map.update(reversed, value, [key], &amp;[key | &amp;1])
    reverse_map(map, reversed)
  end
end

With this solution I'm generating the map
%{a =&gt; t1, b =&gt; t1, c =&gt; t2}

then reversing it and collecting collisions in a list.
But I feel this intermediate map is unnecessary and a solution could exist without it.
In addition I'm not sure my implementation of reverse_map is as elegant as it could be.
defmodule Test do
  def contains?(term, elem) do
    elem in term
  end

  def test do
    elems = [1,2,3]
    terms = [[1,2], [2,3]]
    
    for e &lt;- elems, reduce: %{} do
      acc -&gt;
        key = Enum.find(terms, &amp;contains?(&amp;1, e))
        Map.update(acc, key, [e], &amp;[e|&amp;1])
    end  
    #=&gt; %{[1, 2] =&gt; [2, 1], [2, 3] =&gt; [3]}
  end
end

Found a simple and elegant solution using a reduce comprehension.
Here, we iterate over each elem in elems, find the first term which contains it, then update our map with either term =&gt; [elem] or term =&gt; [elem|previous_elems] depending on if that key exists in the map yet.

Side note:
If I needed the elems in the same as order they were originally I could use &amp; &amp;1 ++ [e] instead of &amp;[e|&amp;1], but as I don't have that requirement it is more efficient to prepend the list.