Erlang 基于元组的模式匹配

Erlang 基于元组的模式匹配,erlang,Erlang,BSON编码的JSON如下所示: { "salutation" : "hello", "subject" : "world" } 进入如下所示的Erlang元组: { salutation, <<"hello">>, subject, <<"world">> } 这可能吗?有更好的方法吗 T = { subject, <<"world">>, salutation, <<"hello">>,

BSON编码的JSON如下所示:

{ "salutation" : "hello",
  "subject" : "world" }
进入如下所示的Erlang元组:

{ salutation, <<"hello">>, subject, <<"world">> }
这可能吗?有更好的方法吗

T = { subject, <<"world">>, salutation, <<"hello">>, reason, <<"nice day">> },
L = size(T),
L1 = [{element(I,T),element(I+1,T)} || I <- lists:seq(1,L,2)].

[{subject,<<"world">>},
 {salutation,<<"hello">>},
 {reason,<<"nice day">>}]

proplists:get_value(salutation,L1).                           
<<"hello">>
如果您想在1中实现所有功能:

F = fun(Key,Tup) -> proplists:get_value(Key,[{element(I,Tup),element(I+1,Tup)} || I <- lists:seq(1,size(Tup),2)]) end.

F(reason,T).
<<"nice day">>
F(foo,T).
undefined
没有模式能够成功匹配未知长度前缀后可变长度结构中的值。元组、列表和二进制文件都是如此。事实上,这种模式需要在结构中递归

列表的一种常见方法是通过拆分头和尾来递归,这是函数式语言的典型特征

f_list([salutation, Salutation | _]) -> {value, Salutation};
f_list([_Key, _Value | Tail]) -> f_list(Tail);
f_list([]) -> false.
请注意,如果列表包含奇数个元素,此函数可能会失败

元组也可以采用相同的方法,但您需要的不是匹配模式,因为没有模式来提取元组尾部的等价物。实际上,元组不是链表,而是对其元素和大小具有O1访问权限的结构

f_tuple(Tuple) -> f_tuple0(Tuple, 1).

f_tuple0(Tuple, N) when element(N, Tuple) =:= salutation ->
    {value, element(N + 1, Tuple)};
f_tuple0(Tuple, N) when tuple_size(Tuple) > N -> f_tuple0(Tuple, N + 2);
f_tuple0(_Tuple, _N) -> false.
同样,如果元组包含奇数个元素,此函数可能会失败


根据问题中的要素,与bson:at/2相比,防护的优势还不清楚。

我已经可以用bson:at做到这一点,尽管这很有用,谢谢。我想知道我是否可以用模式来匹配一个元组的内部元素?我想如果你事先不知道它的长度,也不想把它转换成其他类型,比如列表,那么匹配它是不可能的。
f_list([salutation, Salutation | _]) -> {value, Salutation};
f_list([_Key, _Value | Tail]) -> f_list(Tail);
f_list([]) -> false.
f_tuple(Tuple) -> f_tuple0(Tuple, 1).

f_tuple0(Tuple, N) when element(N, Tuple) =:= salutation ->
    {value, element(N + 1, Tuple)};
f_tuple0(Tuple, N) when tuple_size(Tuple) > N -> f_tuple0(Tuple, N + 2);
f_tuple0(_Tuple, _N) -> false.