将映射作为参数传递到函数中,并从Erlang中的值获取键w.r.t

将映射作为参数传递到函数中,并从Erlang中的值获取键w.r.t,erlang,Erlang,这里的Map是由键和值对组成的Map数据,如 Map = # {"a" => "Apple","b" =>"bat","c" =>"cat ", "d" => "dog","e" => "eagle","f" => "fan &q

这里的Map是由键和值对组成的Map数据,如

Map = # {"a" => "Apple","b" =>"bat","c" =>"cat ",
  "d" => "dog","e" => "eagle","f" => "fan ","g" => "goat",
  "h" =>"hat","i" =>"ink","j" =>"jar","k" =>"king","l" =>"lion ",
  "m" =>"madam","n" =>"nike","o" => "orange","p" =>"pot",
  "q" =>"queue ","r" =>"rat","s" =>"snake","t" =>"tea ",
  "u" =>"umbrella","v" =>"van ","w" =>"wolf ","x" =>"xperia ",
  "y" =>"yawk","z" =>"zoo "}
我正在尝试打印以下内容:

例如:

  • 输入:苹果nike goat lion eagle
  • 预期输出:角度
试用代码:

-module(main).
-export([start/1,func/2]).
start(Str) ->
   Map = # {"a" => "Apple","b" =>"bat","c" =>"cat ","d" => "dog","e" => "eagle","f" => "fan ","g" => "goat","h" =>"hat","i" =>"ink","j" =>"jar","k" =>"king","l" =>"lion ","m" =>"madam","n" =>"nike","o" => "orange","p" =>"pot","q" =>"queue ","r" =>"rat","s" =>"snake","t" =>"tea ","u" =>"umbrella","v" =>"van ","w" =>"wolf ","x" =>"xperia ","y" =>"yawk","z" =>"zoo "},
  Chunks = string:tokens(Str, [$\s]),
  io:format("~n~p",[Chunks]),
  L = func(Chunks,Map),
  io:format("~p",[L]).
func([],#{}) ->
 io:format("~nCompleted~n");
func([First | Rest], Map) ->
    Fun = fun(K, V, Acc) -> 
               if V == First -> [K | Acc]; 
                   true -> Acc
                   end 
                end,
     maps:fold(Fun, [], Map), 
  func(Rest, Map).
有没有人能给我提建议?

你说你的意见是:

Apple nike goat lion eagle
但这不是erlang术语,所以您的输入是无意义的

如果您的输入实际上是字符串
“Apple nike goat lion eagle”
,那么我不确定您为什么需要地图,因为您可以提取每个单词的第一个字母:

-module(a).
-compile(export_all).

get_first_letters_of_words(Sentence) ->
    Words = string:split(Sentence, "\s", all),
    Result = get_first_letters(Words, _Acc=[]),
    io:format("~p~n", [Result]).

get_first_letters([ [Int|_Ints] | Words], Acc) ->
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok
您可以在下面阅读如何使用字符串。返回的单词列表实际上是一个列表,其中每个元素都是一个整数列表,例如

[ [97,98,99], [100,101,102] ]
如果您这样编写,函数
get_first_letters/2
可能更容易理解:

get_first_letters([Word|Words], Acc) ->
    [Int|_Ints] = Word,
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
 "cat" "Apple" "dog"
创建一个以单词为值、以首字母为键的映射也是毫无意义的。相反,您可以创建一个映射,其中单词是键,值是第一个字母,然后您可以使用单词调用来查找第一个字母

如果你有一个映射,其中一个单词/值与多个键相关联,那么事情就有点棘手了。以下示例检索与单词关联的所有键:

-module(a).
-compile(export_all).

get_code_for_words(Sentence) ->
    Words = string:split(Sentence, "\s", all),
    LettersWords = # {"a" => "Apple",
                      "b" => "bat",
                      "c" => "cat",
                      "x" => "bat"},
    Result = get_codes(Words, LettersWords, _AllCodes=[]),
    io:format("~p~n", [Result]).
    
get_codes([Word|Words], Map, AllCodes) ->
    NewAllCodes = maps:fold(fun([K],V,Acc) ->
                   case V =:= Word of
                        true -> [K|Acc];
                        _    -> Acc
                   end
               end,
               AllCodes,
               Map),

    get_codes(Words, Map, NewAllCodes);
get_codes([], _Map, AllCodes) ->
    lists:reverse(AllCodes).
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok

在erlang中,字符串只是创建整数列表的快捷方式,其中列表中的整数是字符串中字符的ascii码

8> "abc" =:= [97, 98, 99].
true
您可能不喜欢这样,但事实就是这样:一个双引号字符串告诉erlang创建一个整数列表。shell具有误导性,因为有时候shell会将字符串“abc”打印为
“abc”
,而不是
[97、98、99]
。为了防止shell误导您,您可以在shell中执行
shell:strings(false)
,然后shell将始终输出字符串的整数列表:

12> shell:strings(false).
true

13> "abc".                     
[97,98,99]
这将持续到shell会话的其余部分(或直到您执行
shell:strings(true)
)。如果需要,您仍然可以显式地告诉shell打印字符串:

16> io:format("~p~n", ["abc"]).
"abc"
ok
使用
[Head | Tail]
匹配整数列表(例如双引号字符串)时,
Head
将匹配一个整数:

9> [Head|Tail] = "abc".
"abc"

10> Head.
97
问题在于映射中的键是字符串,而不是整数。最简单的处理方法是将整数插入列表,将其转换为字符串:

11> [Head].
"a"
以下是一个例子:

-module(a).
-compile(export_all).

get_words(ListOfInts) ->  %% ListOfInts can be a double quoted string
    LettersWords = # {"a" => "Apple",
                      "b" => "bat",
                      "c" => "cat",
                      "d" => "dog"},
    Words = get_words(ListOfInts, LettersWords, _Acc=[]),
    io:format("~p~n", [Words]).

get_words([Int|Ints], Map, Acc) ->
    Letter = [Int],
    Word = maps:get(Letter, Map),
    get_words(Ints, Map, [Word|Acc]);
get_words([], _Map, Acc) -> Acc.
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok
如果希望结果的顺序与输入字符串中的字母相同,则返回
lists:reverse(Acc)
,而不是
Acc

如果要显示每个单词,而不是单词列表,如下所示:

get_first_letters([Word|Words], Acc) ->
    [Int|_Ints] = Word,
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
 "cat" "Apple" "dog"
您可以这样做:

show_results(Words) ->
    lists:foreach(fun(Word) -> io:format("~p ", [Word]) end,
                 Words),
    io:format("~n").
如果不想显示引号,例如:

cat Apple dog
您可以使用
~s
控制序列:

show_results(Words) ->
    lists:foreach(fun(Word) -> io:format("~s ", [Word]) end,
                 Words),
    io:format("~n").
  
您说您的输入是:

Apple nike goat lion eagle
但这不是erlang术语,所以您的输入是无意义的

如果您的输入实际上是字符串
“Apple nike goat lion eagle”
,那么我不确定您为什么需要地图,因为您可以提取每个单词的第一个字母:

-module(a).
-compile(export_all).

get_first_letters_of_words(Sentence) ->
    Words = string:split(Sentence, "\s", all),
    Result = get_first_letters(Words, _Acc=[]),
    io:format("~p~n", [Result]).

get_first_letters([ [Int|_Ints] | Words], Acc) ->
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok
您可以阅读下面有关如何处理字符串的内容。返回的单词列表实际上是一个列表,其中每个元素都是一个整数列表,例如

[ [97,98,99], [100,101,102] ]
如果您这样编写,函数
get_first_letters/2
可能更容易理解:

get_first_letters([Word|Words], Acc) ->
    [Int|_Ints] = Word,
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
 "cat" "Apple" "dog"
创建一个映射,其中单词是值,第一个字母是键,也没有任何意义。相反,您可以创建一个映射,其中单词是键,值是第一个字母,然后您可以使用单词调用以查找第一个字母

如果您实际上有一个映射,其中一个单词/值与多个键关联,那么事情就有点棘手了。以下示例检索与一个单词关联的所有键:

-module(a).
-compile(export_all).

get_code_for_words(Sentence) ->
    Words = string:split(Sentence, "\s", all),
    LettersWords = # {"a" => "Apple",
                      "b" => "bat",
                      "c" => "cat",
                      "x" => "bat"},
    Result = get_codes(Words, LettersWords, _AllCodes=[]),
    io:format("~p~n", [Result]).
    
get_codes([Word|Words], Map, AllCodes) ->
    NewAllCodes = maps:fold(fun([K],V,Acc) ->
                   case V =:= Word of
                        true -> [K|Acc];
                        _    -> Acc
                   end
               end,
               AllCodes,
               Map),

    get_codes(Words, Map, NewAllCodes);
get_codes([], _Map, AllCodes) ->
    lists:reverse(AllCodes).
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok

在erlang中,字符串只是创建整数列表的快捷方式,其中列表中的整数是字符串中字符的ascii码

8> "abc" =:= [97, 98, 99].
true
您可能不喜欢这样,但事实就是这样:双引号字符串告诉erlang创建一个整数列表。shell具有误导性,因为有时shell会将字符串“abc”打印为
“abc”
,而不是
[97,98,99]
。为了防止shell误导您,您可以执行
shell:strings(false)
,然后shell将始终输出字符串的整数列表:

12> shell:strings(false).
true

13> "abc".                     
[97,98,99]
这将持续到shell会话的其余部分(或直到您执行
shell:strings(true)
)。如果需要,您仍然可以显式地告诉shell打印字符串:

16> io:format("~p~n", ["abc"]).
"abc"
ok
使用
[Head | Tail]
匹配整数列表(例如双引号字符串)时,
Head
将匹配一个整数:

9> [Head|Tail] = "abc".
"abc"

10> Head.
97
问题在于映射中的键是字符串,而不是整数。最简单的处理方法是将整数插入列表,将其转换为字符串:

11> [Head].
"a"
以下是一个例子:

-module(a).
-compile(export_all).

get_words(ListOfInts) ->  %% ListOfInts can be a double quoted string
    LettersWords = # {"a" => "Apple",
                      "b" => "bat",
                      "c" => "cat",
                      "d" => "dog"},
    Words = get_words(ListOfInts, LettersWords, _Acc=[]),
    io:format("~p~n", [Words]).

get_words([Int|Ints], Map, Acc) ->
    Letter = [Int],
    Word = maps:get(Letter, Map),
    get_words(Ints, Map, [Word|Acc]);
get_words([], _Map, Acc) -> Acc.
在外壳中:

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

64> a:get_first_letters_of_words("Apple nike goat lion eagle").
"Angle"
ok
79> c(a).                                 
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

80> a:get_code_for_words("Apple bat cat").
"abxc"
ok
3> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

4> a:start("cad").
["dog","Apple","cat "]
ok
如果希望结果的顺序与输入字符串中的字母相同,则返回
lists:reverse(Acc)
,而不是
Acc

如果要显示每个单词,而不是单词列表,如下所示:

get_first_letters([Word|Words], Acc) ->
    [Int|_Ints] = Word,
    get_first_letters(Words, [Int|Acc]);
get_first_letters([], Acc) ->
    lists:reverse(Acc).
 "cat" "Apple" "dog"
您可以这样做:

show_results(Words) ->
    lists:foreach(fun(Word) -> io:format("~p ", [Word]) end,
                 Words),
    io:format("~n").
如果不想显示引号,例如:

cat Apple dog
您可以使用
~s
控制序列:

show_results(Words) ->
    lists:foreach(fun(Word) -> io:format("~s ", [Word]) end,
                 Words),
    io:format("~n").
  

我建议您这样做。当然,为了提高效率,您应该将反向字典存储在某个位置,例如服务器状态

1> % Enter the dictionary
1> Map = # {"a" => "apple","b" =>"bat","c" =>"cat","d" => "dog","e" => "eagle","f" => "fan","g" => "goat","h" =>"hat","i" =>"ink","j" =>"jar","k" =>"king","l" =>"lion","m" =>"madam","n" =>"nike","o" => "orange","p" =>"pot","q" =>"queue","r" =>"rat","s" =>"snake","t" =>"tea","u" =>"umbrella","v" =>"van","w" =>"wolf","x" =>"xperia","y" =>"yawk","z" =>"zoo"}.         
#{"a" => "apple","b" => "bat","c" => "cat","d" => "dog",
  "e" => "eagle","f" => "fan","g" => "goat","h" => "hat",
  "i" => "ink","j" => "jar","k" => "king","l" => "lion",
  "m" => "madam","n" => "nike","o" => "orange","p" => "pot",
  "q" => "queue","r" => "rat","s" => "snake","t" => "tea",
  "u" => "umbrella","v" => "van","w" => "wolf",
  "x" => "xperia","y" => "yawk","z" => "zoo"}
2> % You have a dictionary letters to things while you need a dictionary things to letters. Let's revert it
2> L = maps:to_list(Map). % First trasform into list
[{"a","apple"},
 {"b","bat"},                         
 {"c","cat"},
 {"d","dog"},
 {"e","eagle"},
 {"f","fan"},
 {"g","goat"},
 {"h","hat"},
 {"i","ink"},
 {"j","jar"},
 {"k","king"},
 {"l","lion"},
 {"m","madam"},
 {"n","nike"},
 {"o","orange"},
 {"p","pot"},
 {"q","queue"},
 {"r","rat"},
 {"s","snake"},
 {"t","tea"},
 {"u","umbrella"},
 {"v","van"},
 {"w","wolf"},
 {"x","xperia"},
 {"y","yawk"},
 {"z","zoo"}]
3> IL = [{V,K} || {K,V} <- L]. % exchange Key and Values
[{"apple","a"},
 {"bat","b"},                         
 {"cat","c"},
 {"dog","d"},
 {"eagle","e"},
 {"fan","f"},
 {"goat","g"},
 {"hat","h"},
 {"ink","i"},
 {"jar","j"},
 {"king","k"},
 {"lion","l"},
 {"madam","m"},
 {"nike","n"},
 {"orange","o"},
 {"pot","p"},
 {"queue","q"},
 {"rat","r"},
 {"snake","s"},
 {"tea","t"},
 {"umbrella","u"},
 {"van","v"},
 {"wolf","w"},
 {"xperia","x"},
 {"yawk","y"},
 {"zoo","z"}]
4> IM = maps:from_list(IL). % build the expected dictionary
#{"apple" => "a","bat" => "b","cat" => "c","dog" => "d",                                                                                                             
  "eagle" => "e","fan" => "f","goat" => "g","hat" => "h",
  "ink" => "i","jar" => "j","king" => "k","lion" => "l",
  "madam" => "m","nike" => "n","orange" => "o","pot" => "p",
  "queue" => "q","rat" => "r","snake" => "s","tea" => "t",
  "umbrella" => "u","van" => "v","wolf" => "w",
  "xperia" => "x","yawk" => "y","zoo" => "z"}
5> Input =  ["apple", "nike", "goat", "lion", "eagle"]. % define a test input
["apple","nike","goat","lion","eagle"]
6> lists:reverse(lists:foldl(fun(X,Acc) -> [V] = maps:get(X,IM), [V|Acc] end, [], Input)). % translate
"angle"
7> 
1>%输入字典
1> Map={“a”=>“苹果”,“b”=>“蝙蝠”,“c”=>“猫”,“d”=>“狗”,“e”=>“鹰”,“f”=>“风扇”,“g”=>“山羊”,“h”=>“帽子”,“i”=>“墨水”,“j”=>“罐子”,“k”=>“国王”,“l”=>“狮子”,“m”=>“夫人”,“n”=>“耐克”,“o”=>“橙色”,“p”=>“锅”,“q”=>“队列”,“r”=>“老鼠”