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

oxalkeyp  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(179)

I have defined 2 records:

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

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

And I have created variable which contains port and 3 records:

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 now contains

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

My question is, I want to search record state for some specific pid, example: I want to get true for function find ("B", NewState) and false for function find ("Z", NewState). What is most easiest way to do it?

kg7wmglp

kg7wmglp1#

您可以使用事实,即#client.pid在记录元组中包含pid的索引。
因此,最简单、最高效的解决方案(最多100个客户端,则应更改#state.clients的数据格式以Map或使用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
yhxst69z

yhxst69z2#

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

Clients = NewState#state.clients

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

lists:any(Pred, List)

综合起来

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

相关问题