[erlang-questions] Maps matching syntax - matching on keys that don't exist in a map - Alternative syntax?

Rudolph van Graan rvg.mailing@REDACTED
Wed Jun 4 14:09:19 CEST 2014


Hi there,

I am getting to grips on how one can use maps, but I keep on hitting the same problem. Imagine I have a map which could contain any of three keys : [a,b,c]). Key a is mandatory, the other two may or may not be there depending on business rules:

> convert_map(#{a := ValueA, b := OptionalValueB, c := OptionalValueC}) ->
>   {ValueA,OptionalValueB, OptionalValueC}.

The problem is that this doesn't work if b and c are not present: 

> (system@REDACTED)31> pend:convert_map(#{ a => 1, b => 2, c => 3}).
> {1,2,3}
> (system@REDACTED)32> pend:convert_map(#{ a => 1, b => 2}).
> ** exception error: no function clause matching pend:convert_map(#{a => 1,b => 2}) (pend.erl, line 105)
> (system@REDACTED)33> pend:convert_map(#{ a => 1, c => 3}).
> ** exception error: no function clause matching pend:convert_map(#{a => 1,c => 3}) (pend.erl, line 105)


So do deal with this, I wrote this code:

> convert_map(#{a := A, b := OptionalValueB, c := OptionalValueC}) ->
>     {A,OptionalValueB,OptionalValueC};
> convert_map(Map = #{a := A}) ->
>     {A, value_b(Map), value_c(Map)}.
> 
> 
> value_b(#{ b := OptionalValueB}) -> OptionalValueB;
> value_b(#{})                     -> undefined.
> 
> value_c(#{ c := OptionalValueC}) -> OptionalValueC;
> value_c(#{})                     -> undefined.


which works:

> (system@REDACTED)34> pend:convert_map(#{ a => 1, c => 3}).
> {1,undefined,3}
> (system@REDACTED)35> pend:convert_map(#{ a => 1, c => 2}).
> {1,undefined,2}
> (system@REDACTED)36> pend:convert_map(#{ a => 1, b => 2}).
> {1,2,undefined}

But this feels very clumsy and not Erlang'ish at all. Are there plans for introducing another operator apart from ":=" that will do an optional/default match? Perhaps "~="?

Then the code would like this:

> convert_map(#{a := A, b ~= OptionalValueB, c ~= OptionalValueC}) ->

The same problem will occur when single value access is implemented. I would need a way to extract a key that may or may not be in the map.

Any suggestions?

Rudolph



More information about the erlang-questions mailing list