将 Map 作为参数传递给函数并获取键 w.r.t Erlang 中的值
Passing the Map as argument in a function and get the keys w.r.t the values in Erlang
这里的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 "}
我正在尝试打印以下内容:
示例:
- 输入:apple 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).
在shell中:
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
您可以在下面阅读有关如何使用字符串的信息。由 string:split/3 编辑的单词列表 return 实际上是一个列表,其中每个元素都是一个整数列表,例如
[ [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).
创建一个以单词为值,首字母为键的映射也毫无意义。相反,您将创建一个映射,其中单词是键,值是第一个字母,然后您可以用单词调用 maps:get/2 来查找第一个字母。
如果您实际上有一张地图,其中 word/value 与多个键相关联,那么事情就有点棘手了。以下示例检索与单词关联的所有键:
-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).
在shell中:
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
在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.
在shell中:
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
如果您希望结果与输入字符串中的字母顺序相同,则 return lists:reverse(Acc)
而不是 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>
这里的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 "}
我正在尝试打印以下内容:
示例:
- 输入:apple 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).
在shell中:
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
您可以在下面阅读有关如何使用字符串的信息。由 string:split/3 编辑的单词列表 return 实际上是一个列表,其中每个元素都是一个整数列表,例如
[ [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).
创建一个以单词为值,首字母为键的映射也毫无意义。相反,您将创建一个映射,其中单词是键,值是第一个字母,然后您可以用单词调用 maps:get/2 来查找第一个字母。
如果您实际上有一张地图,其中 word/value 与多个键相关联,那么事情就有点棘手了。以下示例检索与单词关联的所有键:
-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).
在shell中:
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
在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.
在shell中:
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
如果您希望结果与输入字符串中的字母顺序相同,则 return lists:reverse(Acc)
而不是 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>