erlang 尝试将列表的每个元素与Map的键进行比较[我尝试了以下代码]

ix0qys7i  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(154)

I tried the code below , whereas the M1 is the Map consists of M1= #{a =>"Apple",b =>"Ball"}, and Str is the given by user ex: fun("ab").
I want to print the relevant value of the key in Map M1 based on the given string Str.
Tried Code:

fun(Str) ->
  X = [ [X] || X <- Str],
  Key = maps:keys(M1),
  mOrse_convert(X,Key)
end;

mOrse_convert([],Key) ->
  true;

mOrse_convert([First|Rest],Key) ->
  case Key of
     #{ X := A} -> A
  end
  mOrse_convert(Rest,Key)
end.

Can anyone help/suggest me ?

vbkedwbf

vbkedwbf1#

This function has 2 arguments: Str - value to find and target Map . The function returns list of all keys in Map that have value equals Str .

-module(ex).
-export([func/2]).

func(Str, Map) ->
    Fun = fun(K, V, Acc) -> 
                             if V == Str -> [K | Acc]; 
                                    true -> Acc 
                             end 
                end,
    maps:fold(Fun, [], Map).

Go to Erlang shell and type following command:

1> c("ex.erl").
{ok,ex}
2> ex:func("a", #{1 => "a", 2 => "b", 3 => "ab"}).
[1]
3> ex:func("a", #{1 => "a", 2 => "b", 3 => "ab", 4 => "a"}).
[4,1]
bf1o4zei

bf1o4zei2#

Thank you Alexei , the solution provided by you is working good for an alphabet and got the output only for single character and given below, but I want to pass the List as input in as Str , I tried the below code as List as input,
Output for single alphabet :

20> c(morse).                
{ok,morse}
21> morse:morse_convert("s").
Single ok

My Required output is :

20> c(morse).                
{ok,morse}
21> morse:morse_convert("abc").
Apple  Ball Cat ok

Tried Code :

X = [ [X] || X <- Str],
 Y = func(X,Morse),
 io:format(Y  ).
 func([],{}) -> io:fwrite("\nCompleted.\n");
 func([First | Last], Morse) ->
    Fun = fun(K, V, Acc) -> 
                         if K == First -> [V | Acc]; 
                                true -> Acc 
                         end 
            end,
    maps:fold(Fun, [], Morse),
 func(Last,Morse).
qlfbtfca

qlfbtfca3#

-module(a).
-compile(export_all).
    
cypher() ->
   #{"a" =>"Apple",
     "b" => "Ball", 
     "c" => "Cat"}.

convert([]) -> io:format("~n");
convert([Int|Ints]) ->
    Word = maps:get([Int], cypher()),
    io:format("~s ", [Word]),
    convert(Ints).

In the shell:

~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

2> a:convert("abc").
Apple Ball Cat 
ok

3>

An erlang string, e.g. "abc" , is actually a shortcut for creating a list of integers, where each integer is the ascii code of a letter in the string. For example:

3> "abc" =:= [97,98,99].
true

When the shell outputs a string, the shell expects you to know that the string is really a list of integers, which is confusing. To eliminate that confusion, you can tell the shell not to output strings by executing the function shell:strings(false) :

5> "abc".
"abc"

6> shell:strings(false).
true

7> "abc".
[97,98,99]

Then you can see what you are really dealing with.
Next, when you use pattern matching to remove an integer from a list, you have an integer--not a string. To create a string from an integer, you need to put the integer into a list:

[Int]

You can see that here:

2> 97 =:= "a".
false

3> [97] =:= "a".
true

It's not clear whether you have atoms or strings as the keys in your map or whether you don't care. If your map must have atoms as the keys, you can convert strings to atoms using list_to_atom/1 :

8> list_to_atom([97]).
a

Finally, when you want to output a string, e.g. one of the values in the map, rather than a list (after executing shell:strings(false) ), you can use the ~s formatting sequence:

16> io:format("~s~n", ["Apple"]).     
Apple
ok

Using a list comprehension would look like this:

convert(Str) ->
    Cypher = #{"a" =>"Apple",
               "b" => "Ball", 
               "c" => "Cat"
              },
    [
      io:format("~s ", [maps:get([Int], Cypher)] ) 
      || Int <- Str
    ],
    io:format("~n").

A list comprehension always returns a list, in this case [ok, ok, ok] , which is not something you care about--you only care about the side affect of outputting the values. So, you can ignore the list and return something else, i.e. whatever io:format/1 returns, which is ok .
Remember, it's less confusing to have the shell output lists rather than strings, then only output strings when you specifically tell the shell to do it.

4urapxun

4urapxun4#

我不确定是否理解您的要求,这里有两种解释。

1> M = #{a =>"Apple",b =>"Ball",c=>"Corn",d=>"Donut",e=>"Ball"}.
#{a => "Apple",b => "Ball",c => "Corn",d => "Donut",
  e => "Ball"}
2> L = ["Ball","Donut"].                                        
["Ball","Donut"]
3> % first, get list of keys from list of values: expected result = [b,d,e]
3> [K || {K,V} <- maps:to_list(M), lists:member(V,L) == true].  
[b,d,e]
4> L1 = "ace".                                               
"ace"
5> % second, get list of values from list of keys: expected result ["Apple","Corn","Ball"]                
5> [maps:get(list_to_atom([X]),M) || X <- L1].
["Apple","Corn","Ball"]
6>

相关问题