Erlang搜索记录列表中的特定元素

时间:2017-01-19 12:42:35

标签: erlang

我已经定义了2条记录:

-record(state, {port = 9921,
                clients = []
               }
        ).

-record (client, {pid,
                  acc}).

我创建了包含端口和3条记录的变量:

 State = #state{port = 9921, 
                clients = []},
 NewClient1 = #client{pid = "A", acc = <<85>>},
 NewClient2 = #client{pid = "B", acc = <<73>>},
 NewClient3 = #client{pid = "C", acc = <<56>>},
 NewState = State#state{clients = [NewClient1 , NewClient2, NewClient3]},

NewState现在包含

#state{port = 9921,
   clients = [#client{pid = "A",acc = <<"U">>},
              #client{pid = "B",acc = <<"I">>},
              #client{pid = "C",acc = <<25>>}]}

我的问题是,我想搜索某个特定pid的记录状态,例如:我希望函数find(&#34; B&#34;,NewState)为true,函数find为false(&#34; Z&#34;,NewState)。最简单的方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以使用#client.pid在记录元组中包含pid索引的事实。

如此简单和最有效(最多100个客户端,那么您应该更改#state.clients的数据格式以映射或使用ets)解决方案

lists:keyfind(Pid, #client.pid, State#state.clients) =/= false

1> rd(state, {port, clients}).              
state
2> rd(client, {pid, acc}).
client
3> State = #state{port=9921, clients=[#client{pid = "A", acc = <<85>>}, #client{pid = "B", acc = <<73>>}, #client{pid = "C", acc = <<56>>}]}.
#state{port = 9921,
       clients = [#client{pid = "A",acc = <<"U">>},
                  #client{pid = "B",acc = <<"I">>},
                  #client{pid = "C",acc = <<"8">>}]}
4> #client.pid.         
2
5> Find = fun(Pid, State) -> lists:keyfind(Pid, #client.pid, State#state.clients) =/= false end.
#Fun<erl_eval.12.50752066>
6> Find("B", State).
true
7> Find("Z", State).
false

答案 1 :(得分:0)

记录语法允许您使用以下命令访问客户端列表:

Clients = NewState#state.clients

然后你可以使用函数列表:any / 2来检查列表中至少一个元素的条件是否为真:

lists:any(Pred, List)

把所有人放在一起

found(Test, NewState) ->
    lists:any(fun(X) -> X#client.pid == Test end, NewState#state.clients).