通过比较地图中的值来检索键

Posted

技术标签:

【中文标题】通过比较地图中的值来检索键【英文标题】:Retrieving the Keys by comparing the values in a map 【发布时间】:2021-03-03 16:29:42 【问题描述】:

我正在尝试通过将映射的值与作为字符串的给定输入进行比较来打印键(输入在下面尝试执行的示例输出中给出)。

请看下面我试过的代码:

-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

**

请给我建议?

【问题讨论】:

感谢 7stud 的解释,我尝试使用您提供的示例函数 get_code_for_words(Sentence) 来满足我的要求。该函数获取一个句子并将其拆分为单词,然后依次获取每个单词并查看映射中的每个值以找到该单词的匹配项,如果找到匹配项,则将匹配值的键添加到累加器。它工作正常,但输出正在打印。请推荐我? 地图中的值都不是"...." ".." ,那么您希望输出是什么? 在定义的 Map ("a" => ".- ","b" =>"-... ",) 中,我只是去掉了 Map(And我的地图将是 ("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(否则您将不得不逐个字符,但这个函数逐字-word)…

让我们首先使用模式匹配而不是布尔 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" => "--..".

【讨论】:

谢谢@Brujo Benavides,“正如您所见,这些字符串没有尾随空格,就像您地图上的键一样。所以……用下面的地图替换您的地图应该可以解决您的问题…… " 真的解决了我的问题,而且执行得很好。

以上是关于通过比较地图中的值来检索键的主要内容,如果未能解决你的问题,请参考以下文章

通过比较LinkedHashMap中的值来获取密钥

如何通过从数据库中检索值来显示文本框中的值?

通过比较两个输入字段中的值来启用/禁用元素

通过匹配链接表中的值来填充联结表

如何根据值来比较两个地图

通过使用php将表单中的值添加到表列中的现有值来更新数据库中的值的问题