Erlang 如何匹配mochijson2返回的结构?

Erlang 如何匹配mochijson2返回的结构?,erlang,mochiweb,webmachine,mochijson2,Erlang,Mochiweb,Webmachine,Mochijson2,我刚刚开始修补Erlang,正在构建一个非常简单的测试web应用程序,它只是用来显示我的twitter时间线 我正在使用webmachine编写应用程序,并使用erlyDTL呈现模板 我的问题与mochiweb的mochijson2:decode/1函数返回的结构有关 我可以成功获取并删除我的时间线,如以下示例所示: 1> Url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=<TWITTER_

我刚刚开始修补Erlang,正在构建一个非常简单的测试web应用程序,它只是用来显示我的twitter时间线

我正在使用webmachine编写应用程序,并使用erlyDTL呈现模板

我的问题与mochiweb的
mochijson2:decode/1
函数返回的结构有关

我可以成功获取并删除我的时间线,如以下示例所示:

1> Url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=<TWITTER_SCREEN_NAME_HERE>".
2> inets:start().
3> {ok, {_, _, Response}} = httpc:request(Url).
4> DecodedJson = mochijson2:decode(Response).
{{ tweet.text }}  <- works
{{ tweet.created_at }}  <- works
{{ tweet.user.profile_image_url }}  <- ???
但是,要将时间线传递到erlyDTL,我需要去掉
struct
atom标记,只需将一个proplist列表传递给webmachine资源(由erlyDTL呈现)。作为模式匹配的新手,我认为下面的列表理解可以实现这一点:

Timeline = [Tweet || {struct, Tweet} <- DecodedJson].

任何帮助都将不胜感激

根据您描述的结构,您可以尝试:

timeline(List) -> timeline(List, []).

timeline([], Result) -> lists:reverse(Result);
timeline([{struct, S}|T], Result) -> timeline(T, [S|Result]);
timeline([{<<"user">>, {struct, S}}|T], Result) -> timeline(T, [S|Result]);
timeline([_|T], Result) -> timeline(T, Result).

根据您的具体需要,您可能需要将
替换为
。由于您正在处理来自外部世界的输入,您可能还想引入某种类型的输入。

根据您描述的结构,您可以尝试:

timeline(List) -> timeline(List, []).

timeline([], Result) -> lists:reverse(Result);
timeline([{struct, S}|T], Result) -> timeline(T, [S|Result]);
timeline([{<<"user">>, {struct, S}}|T], Result) -> timeline(T, [S|Result]);
timeline([_|T], Result) -> timeline(T, Result).

根据您的具体需要,您可能需要将
替换为
。您可能还想介绍某种类型的,因为您正在处理来自外部世界的输入。

以下是我们内部用于类似目的的内容:

%% @doc Flatten {struct, [term()]} to [term()] recursively.
destruct({struct, L}) ->
    destruct(L);
destruct([H | T]) ->
    [destruct(H) | destruct(T)];
destruct({K, V}) ->
    {K, destruct(V)};
destruct(Term) ->
    Term.

对于mochijson2术语的其他用途,KVC可能对您有用:

以下是我们内部使用的类似用途:

%% @doc Flatten {struct, [term()]} to [term()] recursively.
destruct({struct, L}) ->
    destruct(L);
destruct([H | T]) ->
    [destruct(H) | destruct(T)];
destruct({K, V}) ->
    {K, destruct(V)};
destruct(Term) ->
    Term.

对于mochijson2术语的其他用途,KVC可能对您有用:

在我最近参与的一个项目中,我们处理的是来自前端应用程序的大型JSON数据结构。下面是JSON对象的一个示例(这只是JSON的框架):

现在我决定创建一个模块,将这个结构转换成一个“deep”proplist,这个模块将包含一个函数
struct:all_keys/1
,如果我给它提供struct对象,它将以有组织的方式生成列表和元组。代码如下:

-module(struct). -export([all_keys/1]). is_struct({struct,_}) -> true; is_struct(_) -> false. to_binary(S) when is_list(S)-> list_to_binary(S); to_binary(S) when is_integer(S)-> S; to_binary(S) when is_atom(S)-> to_binary(atom_to_list(S)); to_binary(S) -> S. to_value(V) when is_binary(V)-> binary_to_list(V); to_value(V) when is_integer(V)-> V; to_value(V) when is_list(V)-> try list_to_integer(V) of PP -> PP catch _:_ -> try list_to_float(V) of PP2 -> PP2 catch _:_ -> V end end; to_value(A)-> A. to_value2({struct,L})-> all_keys({struct,L}); to_value2([{struct,_L}|_Rest] = LL)-> [all_keys(XX) || XX <- LL]; to_value2(D) when is_binary(D)-> to_value(D); to_value2(D) when is_list(D)-> [to_value2(Any) || Any <- D]. all_keys({struct,L})-> [{to_value(Key),to_value2(Val)} || {Key,Val} <- L]; all_keys(List)-> [all_keys(X) || X <- List]. 上面的proplist比struct对象更容易使用。但是,您可能会发现struct模块的另一个版本,特别是在一个著名的mochiweb示例中,名为“便笺”,我现在没有它的链接。我上面粘贴的struct模块应该能够帮助您使用mochijson2。
成功

在我最近参与的一个项目中,我们正在处理来自前端应用程序的大型JSON数据结构。下面是JSON对象的一个示例(这只是JSON的框架):

现在我决定创建一个模块,将这个结构转换成一个“deep”proplist,这个模块将包含一个函数
struct:all_keys/1
,如果我给它提供struct对象,它将以有组织的方式生成列表和元组。代码如下:

-module(struct). -export([all_keys/1]). is_struct({struct,_}) -> true; is_struct(_) -> false. to_binary(S) when is_list(S)-> list_to_binary(S); to_binary(S) when is_integer(S)-> S; to_binary(S) when is_atom(S)-> to_binary(atom_to_list(S)); to_binary(S) -> S. to_value(V) when is_binary(V)-> binary_to_list(V); to_value(V) when is_integer(V)-> V; to_value(V) when is_list(V)-> try list_to_integer(V) of PP -> PP catch _:_ -> try list_to_float(V) of PP2 -> PP2 catch _:_ -> V end end; to_value(A)-> A. to_value2({struct,L})-> all_keys({struct,L}); to_value2([{struct,_L}|_Rest] = LL)-> [all_keys(XX) || XX <- LL]; to_value2(D) when is_binary(D)-> to_value(D); to_value2(D) when is_list(D)-> [to_value2(Any) || Any <- D]. all_keys({struct,L})-> [{to_value(Key),to_value2(Val)} || {Key,Val} <- L]; all_keys(List)-> [all_keys(X) || X <- List]. 上面的proplist比struct对象更容易使用。但是,您可能会发现struct模块的另一个版本,特别是在一个著名的mochiweb示例中,名为“便笺”,我现在没有它的链接。我上面粘贴的struct模块应该能够帮助您使用mochijson2。
成功

您能发布一个显示您的问题的实际时间线示例吗?您能发布一个显示您的问题的实际时间线示例吗?我将其作为助手推到一个模块中:destruct(),它工作得非常好。令人惊叹的。非常感谢-也感谢KVC技巧。我把它作为助手推到了一个模块中:destruct(),它工作得非常好。令人惊叹的。非常感谢-也感谢KVC技巧。感谢David-因为我对Erlang非常陌生,所以我将在应用程序中迭代异常处理。现在,我仍然习惯于不用Python范式来思考:-)感谢David-因为我对Erlang非常陌生,所以我将在接下来的过程中迭代异常处理到应用程序中。现在,我仍然习惯于不使用Python范例进行思考:-)我尝试使用您的代码,但发现了一个错误。在“{”from“,”Username“}之前有两个“[[”。但是代码对进一步修改非常有帮助。我尝试使用您的代码,发现一个错误。在“{”from“,”Username“}之前有两个“[[”。但是代码对进一步修改非常有帮助。 -module(struct). -export([all_keys/1]). is_struct({struct,_}) -> true; is_struct(_) -> false. to_binary(S) when is_list(S)-> list_to_binary(S); to_binary(S) when is_integer(S)-> S; to_binary(S) when is_atom(S)-> to_binary(atom_to_list(S)); to_binary(S) -> S. to_value(V) when is_binary(V)-> binary_to_list(V); to_value(V) when is_integer(V)-> V; to_value(V) when is_list(V)-> try list_to_integer(V) of PP -> PP catch _:_ -> try list_to_float(V) of PP2 -> PP2 catch _:_ -> V end end; to_value(A)-> A. to_value2({struct,L})-> all_keys({struct,L}); to_value2([{struct,_L}|_Rest] = LL)-> [all_keys(XX) || XX <- LL]; to_value2(D) when is_binary(D)-> to_value(D); to_value2(D) when is_list(D)-> [to_value2(Any) || Any <- D]. all_keys({struct,L})-> [{to_value(Key),to_value2(Val)} || {Key,Val} <- L]; all_keys(List)-> [all_keys(X) || X <- List]. [{"presence_token",P_token}, {"presence_time",P_time}, {"friend_requests", [[{"from","Username"}, {"type","buddy"}, {"date","DD/MM/YY"}, {"time","HH:Mins:Secs"}, {"name","Your Full name"}, {"email","user@example.com"}]]}, {"group_status", [[{"group_name","ecampus"}, {"status","running"}, {"members",["phil","josh","shazz"]}, {"start_date","DD/MM/YY"}, {"start_time","HH:Mins:Secs"}], [{"group_name","buganda"},{"status","off"}]]}, {"friend_status", [[{"friend","Friend_username"}, {"status","online"}, {"log_on_time","HH:Mins:Secs"}, {"state","available"}, {"name","Friend_Fullname"}, {"email","user@example.com"}], [{"friend","Friend_username"}, {"status","offline"}, {"name","Friend_Fullname"}, {"email","user@example.com"}]]}]