2010-10-28 96 views
6

我想要拿出一个我可以在Erlang中使用的字典式数据结构。我们的目标是确保所有的值以及密钥都是唯一的。我可以在每次修改后都进行明确的一致性检查,但我希望有一个不明确的类型可以帮助我做到这一点。有一个吗?如果没有,是否有更好的方法比将支票包装到修改数据的每个函数中(或返回稍微不同的副本)?在Erlang的双向哈希表

我期望至少有120个元素,但不超过几千,以防万一。

回答

6

什么类似的东西:

-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. 

例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} 
+0

我喜欢这个,但是有没有理由使用'dict:find'而不是'dict:is_key'? – nmichaels 2010-10-28 21:52:47

+0

使用'dict:find'也可以。 (不是我的代码) – rvirding 2010-10-28 22:21:29

+0

你是对的字典:is_key在这里可以稍微好一点。我想到字典:先更新,然后尝试字典:找到 – hdima 2010-10-29 06:26:57

1

有没有?

没有在标准库中,我相信。我会使用一对包含dict()set()的值。

1

您可以使用一个简单的{键,值}列表几百元素:

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.