在Erlang列表中按键查找特定元组(eJabberd HTTP Header)

时间:2015-11-30 17:29:14

标签: http erlang ejabberd

我刚开始使用eJabberd并正在编写一个带HTTP访问的自定义模块。

我已经完成了请求,但我现在正在尝试检索自定义标题以及我遇到问题的地方。

我已经使用了Request记录来获取request_headers列表,并且可以看到它包含了我需要的所有头文件(尽管我之后的那个是关键字和值的二进制字符串某些原因......)如下:

[
    { 'Content-Length', <<"100">> },
    { <<"X-Custom-Header">>, <<"CustomValue">> },
    { 'Host', <<"127.0.0.1:5280">> },
    { 'Content-Type', <<"application/json">> },
    { 'User-Agent', <<"Fiddler">> }
]

这也是我第一次涉及函数式编程,因此从程序角度来看,我会遍历列表并检查密钥是否是我正在查找的密钥并返回值。

为此,我创建了一个函数:

find_header(HeaderKey, Headers) ->
    lists:foreach(
        fun(H) ->
            if
                H = {HeaderKey, Value} -> H;
                true -> false
            end
        end,
        Headers).

有了这个,我得到了错误:

  

非法守卫表达

我甚至不确定我是否正确地这样做,所以我正在寻找一些关于如何在Erlang中处理这种情况的建议(可能还有一般的函数式语言)。 / p>

提前感谢您的任何帮助和建议!

PhilHalf

2 个答案:

答案 0 :(得分:4)

你提到的List被称为&#34;属性列表&#34;,这是一个普通的列表,包含元组形式的条目,其第一个元素是用于查找和插入的键或者原子,作为元组的简写{Atom,true}。

要获取密钥值,您可以执行以下操作:

proplists:get_value(Key,List).

示例获取内容长度:

7> List=[{'Content-Length',<<"100">>},
      {<<"X-Custom-Header">>,<<"CustomValue">>},
      {'Host',<<"127.0.0.1:5280">>},
      {'Content-Type',<<"application/json">>},
      {'User-Agent',<<"Fiddler">>}].

7> proplists:get_value('Content-Type',List).
<<"application/json">>

答案 1 :(得分:2)

您可以使用lists:keyfind/3功能:

> {_, Value} = lists:keyfind('Content-Length', 1, Headers).
{'Content-Length',<<"100">>}
> Value.
<<"100">>

第二个参数中的1告诉函数要比较的元组元素。例如,如果您想知道哪个键与您已知的值相对应,那么您可以使用2代替:

> {Key, _} = lists:keyfind(<<"100">>, 2, Headers).
{'Content-Length',<<"100">>}
> Key.
'Content-Length'

至于如何在Erlang中实现它,你要写一个递归函数。

想象一下,您正在查看列表的第一个元素,试图弄清楚这是否是您正在寻找的条目。有三种可能性:

  1. 列表为空,因此无需比较。
  2. 第一个条目匹配。返回它并忽略列表的其余部分。
  3. 第一个条目不匹配。因此,在此列表中查找此键的结果与在其余元素中查找该键的结果相同:我们递归。
  4. find_header(_HeaderKey, []) ->
        not_found;
    find_header(HeaderKey, [{HeaderKey, Value} | _Rest]) ->
        {ok, Value};
    find_header(HeaderKey, [{_Key, _Value} | Rest]) ->
        find_header(HeaderKey, Rest).
    

    希望这有帮助。