Reputation: 42500
I am new to Elixir and have a question about the map keys. I have a map defined as below:
a = %{"key" => 1}
I am able to access the value by a["key"]
but not a.key
. If I define the map as a = %{key: 1}
, then I am able to get the value by a.key
. I wonder what the different between these two ways of declaring keys.
If I have a function which accept the key by a["key']
and I have a map defined as a = %{key: 1}
, how can I pass this variable to the function?
For example, I have below function:
def fun1(data) do
data.key ... // access key by atom
done
and I have a variable data which is using string as the key. How can I pass this variable to the function?
Upvotes: 4
Views: 15076
Reputation: 1
Get the value by using key
iex(1)> map = %{"a" => 1}
%{"a" => 1}
iex(2)> map["a"]
1
iex(3)> map2 = %{a: 1}
%{a: 1}
iex(4)> map2.a
1
Upvotes: 0
Reputation: 2863
a = %{"key": 12}
used string as key, you can only use a["key"]
to access.
a = %{key: 12}
used atom as key, you can use a[:key]
or a.key
to access.
Note, when there is no this key in the map, a[:key]
will return nil
while a.key
will throw KeyError.
iex(1)> a = %{}
%{}
iex(2)> a[:not_exist]
nil
iex(3)> a.not_exist
** (SyntaxError) iex:7: syntax error before: not_exist
Upvotes: 1
Reputation: 48599
def fun1(data) do data.key ... // access key by atom done
...and I have a variable data which is using string as the key. How can I pass this variable to the function?
my.exs:
defmodule Stuff do
def fun1(data) do
data.a #access key by atom
end
end
In the shell:
~/elixir_programs$ iex my.exs
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> data = %{"a" => 1, "b" => 2} %{"a" => 1, "b" => 2}
iex(2)> new_data = Enum.into(data, %{}, fn {key, val} -> {String.to_atom(key), val} end)
%{a: 1, b: 2}
iex(3)> Stuff.fun1 new_data 1
iex(4)>
Upvotes: 0
Reputation: 10061
These are two different types that are being used for your key.
%{"key" => 1}
is using a string for a key.%{key: 1}
is short hand for %{:key => 1}
which is using an atom for a key.You can only use map.key
syntax if you have atoms for keys.
Upvotes: 11
Reputation: 186
Both ways of accessing the values are syntatic sugar for Map.get/2 function.
So the difference between the two is that atoms are not garbage collected, and they are optimized by the erlang VM for things like pattern matching.
Strings are more general purpose, so because optimizations you should always try to use atoms as keys, if you can.
Now I don't know if I understood your last question, but a good "erlang" way of getting the key you want in that function would be:
as atom:
def fun1(%{key: value}) do
value
end
as string:
def fun1(%{"key" => value}) do
value
end
In both cases it will only enter the function if it matches the pattern, and your value will be already available inside the function.
Upvotes: 2