#erlang #erlang-shell
#erlang #erlang-оболочка
Вопрос:
Я пытаюсь распечатать ключи, сравнивая значения карты с заданными входными данными в виде строки (входные данные приведены в приведенном ниже примере примерного вывода).
Смотрите приведенный ниже код, который я пробовал кодировать:
-module(main).
-compile(export_all).
get_code_for_words(Sentence) ->
Words = string:split(Sentence, "s", all),
LettersWords = # { "a" => ".- ","b" =>"-... ","c" =>"-.-. ","d" => "-.. ","e" => ". ","f" => "..-. ","g" => "--. ","h" =>".... ","i" =>".. ","j" =>".--- ","k" =>"-.- ","l" =>".-.. ","m" =>"-- ","n" =>"-. ","o" => "--- ","p" =>".--. ","q" =>"--.- ","r" =>".-. ","s" =>"... ","t" =>"- ","u" =>"..- ","v" =>"...- ","w" =>".-- ","x" =>"-..- ","y" =>"-.--","z" =>"--.. "},
Result = get_codes(Words, LettersWords, _AllCodes=[]),
io:format("~p~n", [Result]).
get_codes([Word|Words], Map, AllCodes) ->
NewAllCodes = maps:fold(fun(K,V,Acc) ->
%io:format("~p~n",[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).
Когда я выполнил код, результат приведен ниже:
**
9> c(main).
main.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,main}
10> main:get_code_for_words(".... ..").
[]
ok
**
Пожалуйста, предложите мне?
Комментарии:
1. Спасибо 7stud за расширение, я попробовал с помощью предоставленного вами примера функции get_code_for_words(предложение) делает то, о чем я прошу. Функция берет предложение и разбивает его на слова, затем берет каждое слово по очереди и просматривает каждое значение на карте, чтобы найти совпадения для слова, и если совпадение найдено, ключ для соответствующего значения добавляется в накопитель. Он работает правильно, но вывод печатается. Пожалуйста, предложите мне?
2. Ни одно из значений на вашей карте не является
"...."
or".."
, так каким вы ожидаете получить результат?3. В определенной карте («a» => «.- «,»b» =>»-… «,) , Я просто удалил лишнее пространство в значении Map(И моя Карта будет («a» => «.- «,»b» =>»-…»,). Затем значение сравнивается с вводом, я выполнил и получил требуемый результат. Спасибо @7Stud.
Ответ №1:
Давайте сначала переформатируем ваш код (с помощью rebar3_format
):
get_code_for_words(Sentence) ->
Words = string:split(Sentence, "s", all),
LettersWords =
#{"a" => ".- ",
"b" => "-... ",
"c" => "-.-. ",
"d" => "-.. ",
"e" => ". ",
"f" => "..-. ",
"g" => "--. ",
"h" => ".... ",
"i" => ".. ",
"j" => ".--- ",
"k" => "-.- ",
"l" => ".-.. ",
"m" => "-- ",
"n" => "-. ",
"o" => "--- ",
"p" => ".--. ",
"q" => "--.- ",
"r" => ".-. ",
"s" => "... ",
"t" => "- ",
"u" => "..- ",
"v" => "...- ",
"w" => ".-- ",
"x" => "-..- ",
"y" => "-.--",
"z" => "--.. "},
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).
Теперь давайте изолируем карту, чтобы мне не приходилось постоянно копировать ее, и, поскольку это не похоже на escript, давайте просто удалим вызов io:format/2
для результата…
letters_to_words() ->
#{"a" => ".- ",
…
"z" => "--.. "}.
get_code_for_words(Sentence) ->
Words = string:split(Sentence, "s", all),
get_codes(Words, letters_to_words(), _AllCodes = []).
Теперь давайте поговорим о get_codes/3
…
Поскольку эта функция использует приведенную выше карту, я предполагаю, что вы, когда говорите Word
, на самом деле имеете в виду Character
(поскольку в противном случае вам придется переходить от символа к символу, но эта функция выполняется слово за словом)…
Давайте сначала используем сопоставление с образцом вместо логического case
оператора…
get_codes([Word | Words], Map, AllCodes) ->
NewAllCodes =
maps:fold(fun(K, V, Acc) ->
case V of
Word -> [K | Acc];
_ -> Acc
end
end,
AllCodes,
Map),
get_codes(Words, Map, NewAllCodes);
get_codes([], _Map, AllCodes) ->
lists:reverse(AllCodes).
Теперь я предполагаю, что вы ожидаете, что это произойдет…
8> a_module:get_code_for_words(".- -.-.").
["a","c"]
Но вместо этого вы получаете…
8> a_module:get_code_for_words(".- -.-.").
[]
И, чтобы понять, почему это происходит, давайте посмотрим, каков результат string:split/3
в вашем случае…
9> string:split(".- -.-.", "s", all).
[".-","-.-."]
Как вы можете видеть, в этих строках нет конечных пробелов, как в ключах на вашей карте. Итак … замена вашей карты на следующую должна решить вашу проблему…
letters_to_words() ->
#{"a" => ".-",
"b" => "-...",
"c" => "-.-.",
"d" => "-..",
"e" => ".",
"f" => "..-.",
"g" => "--.",
"h" => "....",
"i" => "..",
"j" => ".---",
"k" => "-.-",
"l" => ".-..",
"m" => "--",
"n" => "-.",
"o" => "---",
"p" => ".--.",
"q" => "--.-",
"r" => ".-.",
"s" => "...",
"t" => "-",
"u" => "..-",
"v" => "...-",
"w" => ".--",
"x" => "-..-",
"y" => "-.--",
"z" => "--.."}.
Комментарии:
1. Спасибо @Brujo Benavides за это «Как вы можете видеть, в этих строках нет конечных пробелов, как в ключах на вашей карте. Итак … замена вашей карты на следующую должна решить вашу проблему …» на самом деле это решило мою проблему и отлично ее выполнило.