Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching maps as function arguments

Tags:

elixir

I'm having trouble writing function clauses where I need to pattern-match against the map and also retain it for use in the function. I'm not able to understand what the syntax will be. Basically I want something like this:

def check_data (arg1, %{"action" => "action1", ...}, arg2) do
  # access other keys of the structure
end

I'm sure this is very basic, but it's something that seems to be eluding me. I've gone through many tutorials but can't seem to find one that handles this use case.

like image 268
ankush981 Avatar asked Dec 19 '22 13:12

ankush981


1 Answers

To match some keys of a map and also store the whole map in a variable, you can use = variable with the pattern:

def check_data(arg1, %{"action" => "action1"} = map, arg2) do
end

This function will match any map containing the "action1" in the key "action" (and any other key/value pairs) as the 2nd argument, and store the whole map in map:

iex(1)> defmodule Main do
...(1)>   def check_data(_arg1, %{"action" => "action1"} = map, _arg2), do: map
...(1)> end
iex(2)> Main.check_data :foo, %{}, :bar
** (FunctionClauseError) no function clause matching in Main.check_data/3
    iex:2: Main.check_data(:foo, %{}, :bar)
iex(2)> Main.check_data :foo, %{"action" => "action1"}, :bar
%{"action" => "action1"}
iex(3)> Main.check_data :foo, %{"action" => "action1", :foo => :bar}, :bar
%{:foo => :bar, "action" => "action1"}
like image 115
Dogbert Avatar answered Jan 01 '23 22:01

Dogbert