这与"Convert tuples to proplists"相反。
我有一个Erlang proplist,可能包含重复键:
P = [{foo, "bar"}, % key = string (char list)
baz, {quux, true}, % both true; one expanded
{dog, "Rex"}, % this overrides the duplicate below
{sum, 42}, % key = integer
{dog, "Fido"}, % overriden above
{colour, blue}, % key = atom
{always, false}]. % opposite of baz or quux
我想把它变成一个配对的元组(适用于bson-erlang),如下所示:
{foo, "bar",
baz, true, % atom => {atom, true} => ..., atom, true, ...
quux, true,
dog, "Rex", % the first one.
sum, 42,
colour, blue,
always, false}
所以,[{k1, v1}, {k2, v2}, ...]
现在是{k1, v1, k2, v2, ...}
。
该名单扩大了;重复键使用正确的值(第一个,由proplists:get_value/2
返回)。在这种情况下,生成的元组中的键的顺序并不特别重要。
我如何在Erlang中执行此操作?
答案 0 :(得分:2)
到目前为止,我想出的最好成绩如下:
paired_tuple_from_proplist(P) ->
% This is a hack, but uses the fact that orddict:from_list
% removes duplicates. Unfortunately, later overrides earlier
% which is the other way round from proplists. Hence the reverse.
D = orddict:from_list(lists:reverse(proplists:unfold(P))),
L = paired_list_from_orddict(D),
list_to_tuple(L).
paired_list_from_orddict(D) ->
paired_list_from_orddict(D, []).
paired_list_from_orddict([], Acc) ->
Acc; % DON'T reverse the list.
paired_list_from_orddict([{K,V}|Rest], Acc) ->
paired_list_from_orddict(Rest, [K,V|Acc]).
答案 1 :(得分:0)
p([{K,V}|T]) -> [K,V|p(T)];
p([S|T]) -> [S,true|p(T)];
p([]) -> [].
答案 2 :(得分:0)
简而言之,但我担心长篇名单效率不高:
5> P = [{foo, "bar"},baz, {quux, true},{dog, "Rex"},{sum, 42},{dog, "Fido"},{colour, blue},{always, false}].
[{foo,"bar"},baz,{quux,true},{dog,"Rex"},{sum,42},{dog,"Fido"},{colour,blue},{always,false}]
6> F = fun({X,Y},{A1,A2}) -> case lists:member(X,A1) of true -> {A1,A2}; _ -> {[X|A1],[X,Y|A2]} end;
(X,{A1,A2}) -> case lists:member(X,A1) of true -> {A1,A2}; _ -> {[X|A1],[X,true|A2]} end end.
#Fun<erl_eval.12.80484245>
7> {_,L2} = lists:foldr(F,{[],[]},P).
{[foo,baz,quux,sum,dog,colour,always],[foo,"bar",baz,true,quux,true,sum,42,dog,"Fido",colour,blue,always,false]}
8> list_to_tuple(L2).
{foo,"bar",baz,true,quux,true,sum,42,dog,"Fido",colour,blue,always,false}
答案 3 :(得分:0)
我想出了这个。
它只是一个功能!
(把它写成一个单行,可以在lists:foldl/3
调用之外定义好玩,以获得更好的格式化。)
toPairedList(ListIn) ->
ListOut = lists:foldl(fun(Key,Acc) ->
[Val|_] = proplists:get_all_values(Key,ListIn),
[Key,Val | Acc]
end
,[]
,proplists:get_keys(ListIn)),
list_to_tuple(ListOut).
该死的,我讨厌这些练习,他们正在削弱我的生产力。
仍然是一个较短的变体,使用lists:flatmap/2
,因此不再需要累加器。
toPairedList(ListIn) ->
Job = fun(Key) -> [Val|_] = proplists:get_all_values(Key,ListIn),
[Key,Val] end,
list_to_tuple(lists:flatmap(Job ,proplists:get_keys(ListIn))).
结果:
> toPairedList([{foo, "bar"},baz, {quux, true}, {dog, "Rex"}, {sum, 42}, {dog, "Fido"}, {colour, blue}, {always, false}]).
{colour,blue,always,false,dog,"Rex",quux,true,baz,true,sum,42,foo,"bar"}