Erlang:在列表中创建元组列表:foreach

时间:2016-07-15 22:41:53

标签: foreach erlang

我在Chicagoboss的Mnesia数据库中查询用户列表。当我尝试在列表中添加列表时,我收到错误:foreach with ++ operator。我的目标是,基于用户ID我会做:ets:查找我的缓存并创建一个列表,如 - [{{<<“名称”>>,<<“蝙蝠侠”>>}, {<<“steps”>>,2552},{<<“distance”>>,2050}}]。

对于每个用户,我将创建此列表并添加上一个列表。所以我最终可以对<<“steps”>>进行排序并通过json编码转换二进制列表,并通过Websockets将其发送到客户端。

我在这一行收到错误: Reading1 = Reading2 ++ Currentlist

因为我将Reading1称为空列表。

我的问题是如何操作列表中的列表:foreach然后通过websocket发送结果列表?

        BelugaUsers = boss_db:find(users, [{accesstoken, 'not_equals', ''}]),
        Reading1 = [],
        Reading2 = [],
        lists:foreach(fun(X) ->         
        {_,_,BEmail,BName,_,_,BAccessToken,_} = X,
        UserKey = BEmail ++ "-" ++ ?MYAPICALL1,
        io:format("UserKey for Leader Board: ~n~p~n",[UserKey]),
        [Reading] = ets:lookup(myapi_cache, list_to_binary(UserKey)),
        {_,Result} = Reading,

        ActivitySummary = proplists:get_value(<<"activitySummary">>, Result),
        %Print ActivitySummary for the user ....printing fine 
        io:format("ActivitySummary ==========: ~n~p~n",[ActivitySummary]),

        %Create a list of the format
        %[{{<<"name">>,<<"Batman">>}, {<<"steps">>,2552}, {<<"distance">>,2050}}]

        Currentlist = [{{<<"name">>, list_to_binary(BName)}, {<<"steps">>, proplists:get_value(<<"steps">>, ActivitySummary)}, {<<"distance">>, proplists:get_value(<<"distance">>, ActivitySummary)}}],
        %% HERE I'M GETTING error%%
        Reading1 = Reading2 ++ Currentlist
        end, BelugaUsers),
        %sort the list
        Reading3 = lists:keysort(2, Reading1),
        %reverse the list
        Reading4 = lists:reverse(Reading3),
        WebSocketId ! {text, jsx:encode(Reading4)},

1 个答案:

答案 0 :(得分:3)

Erlang变量是单一赋值;一旦绑定到一个值,它们就不能重新绑定到不同的值。

lists:foreach/2函数对此问题没有用,因为它无法创建新值并将其返回给调用者。你应该使用lists:map/2,或许像这样:

BelugaUsers = boss_db:find(users, [{accesstoken, 'not_equals', ''}]),
Reading = lists:map(
            fun(X) ->
                    {_,_,BEmail,BName,_,_,BAccessToken,_} = X,
                    UserKey = BEmail ++ "-" ++ ?MYAPICALL1,
                    io:format("UserKey for Leader Board: ~n~p~n",[UserKey]),
                    {_,Result} = hd(ets:lookup(myapi_cache, list_to_binary(UserKey))),

                    ActivitySummary = proplists:get_value(<<"activitySummary">>, Result),
                    %%Print ActivitySummary for the user ....printing fine
                    io:format("ActivitySummary ==========: ~n~p~n",[ActivitySummary]),

                    %%Create a tuple of the format
                    %%{{<<"name">>,<<"Batman">>}, {<<"steps">>,2552}, {<<"distance">>,2050}}
                    {{<<"name">>, list_to_binary(BName)},
                     {<<"steps">>, proplists:get_value(<<"steps">>, ActivitySummary)},
                     {<<"distance">>, proplists:get_value(<<"distance">>, ActivitySummary)}}
            end, BelugaUsers),
%%sort the list
Reading2 = lists:keysort(2, Reading),
%%reverse the list
Reading3 = lists:reverse(Reading2),
WebSocketId ! {text, jsx:encode(Reading3)}.

lists:map/2函数将函数应用于列表中的每个值,以生成可能不同的值,并返回包含这些新值的新列表。这基本上是您尝试使用lists:foreach/2并尝试使用命令式分配将每个元素添加到已存在的列表中。

您也可以使用list comprehension,但我认为lists:map/2在这种情况下更清晰。