简体   繁体   English

Erlang中的双向哈希表

[英]Two-way Hash Table in Erlang

I'm trying to come up with a dictionary-like data structure that I can use in Erlang. 我试图想出一个类似字典的数据结构,我可以在Erlang中使用它。 The goal is to guarantee that all the values, as well as the keys, are unique. 目标是保证所有值以及密钥都是唯一的。 I can do it with explicit consistency checks after every modification, but I'm hoping there's an obscure type that does this for me. 我可以在每次修改后通过显式一致性检查来做到这一点,但我希望有一个模糊的类型可以为我做这个。 Is there one? 有吗? If not, is there a better way than wrapping a check into every function that modifies the data (or returns a slightly different copy)? 如果没有,有没有比将支票包装到修改数据的每个函数(或返回稍微不同的副本)更好的方法?

I'm expecting to have at least 120 elements and no more than a few thousand, in case that matters. 我希望至少有120个元素,不超过几千个,如果重要的话。

What about something like that: 这样的事情怎么样:

-module(unidict).

-export([
    new/0,
    find/2,
    store/3
    ]).


new() ->
    dict:new().


find(Key, Dict) ->
    dict:find({key, Key}, Dict).


store(K, V, Dict) ->
    Key = {key, K},
    case dict:is_key(Key, Dict) of
        true ->
            erlang:error(badarg);
        false ->
            Value = {value, V},
            case dict:is_key(Value, Dict) of
                true ->
                    erlang:error(badarg);
                false ->
                    dict:store(Value, K, dict:store(Key, V, Dict))
            end
    end.

Example shell session: 示例shell会话:

1> c(unidict).
{ok,unidict}
2> D = unidict:new().
{dict,0,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}
3> D1 = unidict:store(key, value, D).
{dict,2,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],
        [[{key,key}|value],[{value,...}|{...}]],
        []}}}
4> D2 = unidict:store(key, value, D1).
** exception error: bad argument
     in function  unidict:store/3
5> D2 = unidict:store(key2, value, D1).
** exception error: bad argument
     in function  unidict:store/3
6> D2 = unidict:store(key, value2, D1).
** exception error: bad argument
     in function  unidict:store/3
7> D2 = unidict:store(key2, value2, D1).
{dict,4,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],
        [[{key,key2}|value2]],
        [],[],[],[],[],[],[],[],[],[],[],
        [[{value,value2}|{key,key2}]],
        [[{key,key}|value],[{value,...}|{...}]],
        []}}}
8> unidict:find(key, D2).
{ok,value}
9> unidict:find(key2, D2).
{ok,value2}

Is there one? 有吗?

Not in the standard library, I believe. 我相信不在标准库中。 I would use a pair consisting of a dict() and a set() of values. 我会使用一对由dict()和一set()set()对。

You can use a simple {key, value} list for a couple of hundred elements: 您可以使用简单的{key,value}列表来表示几百个元素:

put(L, K, V) ->
  case lists:keyfind(K, 1, L) of
    {K, _} -> erlang:error(badarg);
    false ->
      case lists:keyfind(V, 2, L) of
        {_, V} -> erlang:error(badarg);
        false ->  [{K,V} | L]
      end
  end.

get(L, K) ->
  case lists:keyfind(K, 1, L) of
    {K, V} -> {'value', V};
    false ->  'undefined'
  end.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM