2010-10-28 74 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.