[erlang-questions] Maps and binaries

Bob Cowdery bob@REDACTED
Wed Dec 12 15:58:54 CET 2018


Hi Hugo

Thanks, all good points. This is test code just sorting out how to do 
things. I have a problem with encoding now.

This is my map:

msg(set_audio_route) -> #{<<"cmd">> => <<"set_audio_route">>, 
<<"params">> => []};

to which I add parameters and encode.
PMsg = maps:put(<<"params">>, [1, "LOCAL", 1, Api, Dev, "BOTH"], 
msg(set_audio_route)),
FullMsg = jsone:encode(PMsg),

This encodes to:

SetRoute - 
<<"{\"cmd\":\"set_audio_route\",\"params\":[1,[76,79,67,65,76],1,[77,77,69],[83,112,101,97,107,101,114,115,32,40,82,101,97,108,116,101,107,32,72,105,103,104,32,68,101,102,105,110,105,116,105],[66,79,84,72]]}">>

The problem is my C lib when I decode the Json is expecting strings in 
the list and it gets lists. I'm doing this in a few languages at the 
moment so can't change the C for one language when its working for 
others. Is there a way around this?

Bob)

On 12/12/2018 10:37, Hugo Mills wrote:
>     Hi, Bob,
>
> On Wed, Dec 12, 2018 at 10:24:35AM +0000, Bob Cowdery wrote:
>> Its a long time since using Erlang so just getting back in. I know
>> that there is always better ways to do things so is there a better
>> patten matching way than this straight forward step-wise method.
>> I have output from a UDP request put through jstone:decode which
>> ends up like so:
>> #{<<"outputs">> =>
>>        [#{<<"api">> => <<"MME">>,<<"channels">> => 2,<<"direction">> => 1,
>>           <<"index">> => 5,<<"name">> => <<"Microsoft Sound Mapper -
>> Output">>},
>>         #{<<"api">> => <<"MME">>,<<"channels">> => 8,<<"direction">> => 1,
>>           <<"index">> => 6,<<"name">> => <<"Speakers (Realtek High
>> Definiti">>},
>> ...
>>       #{<<"api">> => <<>>,<<"channels">> => 0,<<"direction">> => 0,
>>           <<"index">> => 0,<<"name">> => <<>>}]}
>> I want to extract the second member api and name.
>>
>>      Map = jsone:decode(Resp),
>>      List = maps:get(<<"outputs">>, Map),
>>      Element = lists:nth(2, List),
>>      Api = my_binary_to_list(maps:get(<<"api">>, Element)),
>>      Dev = my_binary_to_list(maps:get(<<"name">>, Element)),
>>      io:format("~p, ~p~n", [Api, Dev]).
>     This seems perfectly reasonable as it is. However, you can
> pattern-match maps this way:
>
>     #{<<"outputs">> := List} = Map
>
> and if you know that it's always going to be the second entry in the
> list, you can pattern-match that with this:
>
>     [_, Element | _] = List
>
>     Note that with the map pattern, the key must always be either a
> literal or a bound variable. Also note the required use of :=, which
> is the "mandatory key" syntax, as opposed to =>, which is "optional
> key". You can match multiple key/value pairs in a map in a single
> pattern.
>
>> my_binary_to_list(<<H,T/binary>>) ->
>>      [H|my_binary_to_list(T)];
>> my_binary_to_list(<<>>) -> [].
>     Why not just use binary_to_list/1 in the erlang module?
>
>     Hugo.
>
>> prints:
>>
>> "MME", "Speakers (Realtek High Definiti"
>>
>> Thanks in advance, Bob
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list