Карта с записью в качестве ключа — как проверить, существует ли ключ в Erlang

#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 : меньше памяти и может прекратиться раньше, если вы найдете подходящий ключ. Но код был бы значительно сложнее.