Why not just divide it into two functions that match on having a :c atom (if you want to match on binary keys too, then adding another function that matches on it) and recur, returning the accumulator if no map with :c is passed?
defmodule Test do
def get_c(acc, %{:c => c}), do: Test.get_c([c | acc], c)
def get_c(acc, _), do: acc
end
iex(4)> defmodule Test do
...(4)> def get_c(acc, %{:c => c}), do: Test.get_c([c | acc], c)
...(4)> def get_c(acc, _), do: acc
...(4)> end
{:module, Test,
<<70, 79, 82, 49, 0, 0, 3, 248, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 85,
0, 0, 0, 9, 11, 69, 108, 105, 120, 105, 114, 46, 84, 101, 115, 116, 8, 95,
95, 105, 110, 102, 111, 95, 95, 9, 102, ...>>, {:get_c, 2}}
iex(5)> Test.get_c([], %{a: 'test', c: %{a: false, b: true, c: %{c: 1, b: 2, d: 3}}})
[1, %{b: 2, c: 1, d: 3}, %{a: false, b: true, c: %{b: 2, c: 1, d: 3}}]
In case you want to customise at runtime the key that you dig for you could use a case,
def get_arbitrary(acc, %{} = map, key) do
case map[key] do
nil -> acc
value -> get_arbitrary([value | acc], value, key)
end
end
def get_arbitrary(acc, _, _), do: acc


















