2016-07-15 75 views
1

我從Chicagoboss的Mnesia數據庫中查詢用戶列表。當我嘗試在列表中添加列表時出現錯誤:foreach with ++ operator。我的目標是基於用戶標識符,我將執行ets:查找我的緩存並創建一個列表,例如 - [{{{名稱>>,< < <「蝙蝠俠」>>},{< <「steps」>> ,2552},{< <「distance」>>,2050}}]。Erlang:創建列表中的元組列表:foreach

對於每個用戶,我將創建此列表並添加上一個列表。因此,最終我可以對< <「steps」>>進行排序,並通過json編碼轉換二進制列表並通過Websockets將其發送到客戶端。

,我發現了錯誤,在這一行: Reading1 = Reading2 ++ Currentlist

,因爲我已經decalred 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)}, 

回答

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在這種情況下更清晰。

+0

謝謝史蒂夫! – raich