#erlang #maps #record
#erlang #Карты #запись
Вопрос:
Я хотел бы создать карту, в которой есть запись в качестве ключа и список в качестве значения, но у меня проблема с проверкой, существует ли уже аналогичный ключ — или, скорее, я не знаю, как заставить его работать в Erlang.
У меня есть запись с тремя значениями, и мне нужно проверить, есть ли на карте ключ, который имеет хотя бы одно значение, равное.
Я вижу это таким образом:
-record(r, {A, B, C}).
addRecord(newA, newB, newC, Map) ->
case maps:is_key(#r{A = newA, B = _, C = _}, Map) or maps:is_key(#r{A = _, B = newB, C = _}, Map) or maps:is_key(#r{A = _, B = _, C = newC}, Map) of
true -> threo("...")
_ -> maps:put(#r(A = newA, B = newB, C = newC), [], Map)
end.
Моя идея состояла в том, чтобы указать _ как «любое значение» в maps:is_key, но это не работает в Erlang.
У вас есть какие-либо идеи, как это проверить (возможно, легко)?
Ответ №1:
Ну, нет особенно дешевого способа сделать это. Возможно, вам потребуется проверить все ключи карты. Простой способ заключается в
lists:any(fun(X) ->
is_record(X, r) andalso
(X#r.A == newA orElse X#r.B == newB orElse X#r.C == newC)
end,
maps:keys(Map))
(Я использовал A
и т.д., как в вашем примере, чтобы упростить сравнение, но имена полей должны быть атомами, поэтому они должны быть a
или 'A'
).
Более дешевый способ — использовать maps:iterator
: меньше памяти и может прекратиться раньше, если вы найдете подходящий ключ. Но код был бы значительно сложнее.