从一组嵌套记录创建一个proplist

时间:2013-09-18 08:10:10

标签: erlang

我无法弄清楚如何将嵌套记录的结构转换为支持列表。我可以将个人记录转换为支持列表:

lists:zip(record_info(fields,typea), tl(tuple_to_list(Atypea))).

但是当记录的结构包含其他记录的列表时,这显然会失败:

-record(typec, {
  id = 0,
  name = <<"typec">>,
 })

-record(typeb, {
  id = 0,
  name = <<"typeb">>,
  typec_list = [],
 }).

-record(typea, {
  id = 0,
  name = <<"typea">>,
  typec_list = [],
  typeb_list = [],
 }).

我知道如何才能实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

这可行:

to_proplist(C = #typec{}) -> lists:zip(record_info(fields, typec), tl(tuple_to_list(C)));
to_proplist(B = #typeb{}) ->
    B1 = B#typeb{typec_list = [to_proplist(C) || C <- B#typeb.typec_list]},
    lists:zip(record_info(fields, typeb), tl(tuple_to_list(B1)));
to_proplist(A = #typea{}) ->
    A1 = A#typea{typec_list = [to_proplist(C) || C <- A#typea.typec_list]},
    A2 = A1#typea{typeb_list = [to_proplist(B) || B <- A1#typea.typeb_list]},
    lists:zip(record_info(fields, typea), tl(tuple_to_list(A2))).

如果您想省去为每种相关类型扩展此问题的麻烦,我刚刚找到了这个runtime record_info,但我还没有尝试过。

答案 1 :(得分:2)

由filmor给出的解决方案的变化如下

to_proplist(Record) ->
    to_proplist(Record,[]).


to_proplist(Type = #typea{}, []) ->
    lists:zip(record_info(fields, typea), to_list(Type));

to_proplist(Type = #typeb{}, []) ->
    lists:zip(record_info(fields, typeb), to_list(Type));

to_proplist(Type = #typec{}, []) ->
    lists:zip(record_info(fields, typec), to_list(Type));

to_proplist([NotAType | Rest], Res) ->
    to_proplist(Rest, [to_proplist(NotAType,[])| Res]);

to_proplist([], Res) ->
    lists:reverse(Res);

to_proplist(Val, []) ->
    Val.


to_list(Type) ->
    [to_proplist(L,[]) || L <- tl(tuple_to_list(Type))].

这适用于所有记录组合。只有通过添加case子句,才能支持其他记录。例如:

to_proplist(Type = #typed{}, []) ->
        lists:zip(record_info(fields, typed), to_list(Type));