简体   繁体   English

通过在Erlang列表中找到键来查找特定的元组(eJabberd HTTP标头)

[英]Find a specific tuple by key in an Erlang list (eJabberd HTTP Header)

I am just getting started with eJabberd and am writing a custom module with HTTP access. 我刚刚开始使用eJabberd,正在编写具有HTTP访问权限的自定义模块。

I have the request going through, but am now trying to retrieve a custom header and that's where I'm having problems. 我正在处理请求,但现在尝试检索自定义标头,这就是我遇到的问题。

I've used the Request record to get the request_headers list and can see that it contains all of the headers I need (although the one I'm after is a binary string on both the key and value for some reason...) as follows: 我已经使用Request记录来获取request_headers列表,并且可以看到它包含了我需要的所有标头(尽管出于某种原因,我想要的标头在键和值上都是二进制字符串...)如下:

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

This is also my first foray into functional programming, so from procedural perspective, I would loop through the list and check if the key is the one that I'm looking for and return the value. 这也是我对函数式编程的首次尝试,因此从过程的角度来看,我将遍历该列表,并检查键是否为我要查找的键并返回值。

To this end, I've created a function as: 为此,我创建了一个函数为:

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

With this I get the error: 有了这个我得到的错误:

illegal guard expression 非法守卫表达

I'm not even sure I'm going about this the right way so am looking for some advice as to how to handle this sort of scenario in Erlang (and possibly in functional languages in general). 我什至不确定我是否会以正确的方式进行操作,因此正在寻找有关如何在Erlang中处理这种情况(以及可能在一般的功能语言中)的一些建议。

Thanks in advance for any help and advice! 预先感谢您的任何帮助和建议!

PhilHalf 菲尔·哈尔夫

The List that you have mentioned is called a "Property list", which is an ordinary list containing entries in the form of either tuples, whose first elements are keys used for lookup and insertion or atoms, which work as shorthand for tuples {Atom, true}. 您提到的列表称为“属性列表”,它是一个普通列表,其中包含以下形式的条目:元组(其第一个元素是用于查找和插入的键或原子),它们用作元组的简写{Atom,真正}。

To get a value of key, you may do the following: 要获取键的值,您可以执行以下操作:

proplists:get_value(Key,List).

for Example to get the Content Length: 例如获取内容长度:

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">>

You can use the function lists:keyfind/3 : 您可以使用功能lists:keyfind/3

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

The 1 in the second argument tells the function what tuple element to compare. 第二个参数中的1告诉函数要比较的元组元素。 If, for example, you wanted to know what key corresponds to a value you already know, you'd use 2 instead: 例如,如果您想知道什么键对应于您已经知道的值,则可以使用2

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

As for how to implement this in Erlang, you'd write a recursive function. 至于如何在Erlang中实现这一点,您将编写一个递归函数。

Imagine that you're looking at the first element of the list, trying to figure out if this is the entry you're looking for. 想象一下,您正在查看列表的第一个元素,试图找出这是否是您要查找的条目。 There are three possibilities: 有三种可能性:

  1. The list is empty, so there is nothing to compare. 该列表为空,因此没有可比较的内容。
  2. The first entry matches. 第一个条目匹配。 Return it and ignore the rest of the list. 返回它并忽略列表的其余部分。
  3. The first entry doesn't match. 第一项不匹配。 Therefore, the result of looking for this key in this list is the same as the result of looking for it in the remaining elements: we recurse. 因此,在此列表中查找此键的结果与在其余元素中查找该键的结果相同:我们递归。

find_header(_HeaderKey, []) ->
    not_found;
find_header(HeaderKey, [{HeaderKey, Value} | _Rest]) ->
    {ok, Value};
find_header(HeaderKey, [{_Key, _Value} | Rest]) ->
    find_header(HeaderKey, Rest).

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM