2012-06-03 6 views
7

Ich bin neu bei Erlang und vielleicht habe ich gerade dieses Problem im Tutorial verpasst, obwohl es trivial ist. Nehmen wir an, ich habe eine Liste von {key, Value} -Paaren, die von erlang abgerufen wurden: fun_info/1. Ich möchte Funktionsartigkeit wissen, der Rest der Liste interessiert mich nicht. Also schreibe ich so etwas wie:Einen Wert in {key, value} in Erlang finden

find_value(_, []) -> 
    nothing; 
find_value(Key, [{Key, Value} | _]) -> 
    Value; 
find_value(Key, [_ | T]) -> 
    find_value(Key, T).  

Und dann tun:

find_value(arity, erlang:fun_info(F)). 

I funktioniert gut, aber sollte so etwas wie find_value eine allzu häufig Routine sein, es zu schreiben? Ich habe jedoch sein Analogon in BIFs nicht gefunden. Die Frage ist also: gibt es eine schöne elegante Möglichkeit, um einen Wert für einen Schlüssel aus einer Liste von {key, value} Tupeln zu erhalten?

Antwort

10

lists:keyfind/3 tut dies. Hier habe ich es in Ihren find_value/2 Schnittstelle abgebildet:

find_value(Key, List) -> 
    case lists:keyfind(Key, 1, List) of 
     {Key, Result} -> Result; 
     false -> nothing 
    end. 

proplists sein kann, ein noch besserer Weg, though.

4

Da Listen: keyfind/3 bereits gebucht wurde, werde ich eine weitere nützliche Option erwähnen, Listen Comprehensions mit:

hd([ Value || {arity, Value} <- List ]). 

Das bedeutet, alle Werte bekommen, so dass jedes Element „Wert“ und kommt aus ein Tupel, das innerhalb der Liste {arity, Value} entspricht. Da ein Listenverständnis eine Liste zurückgibt, erhalten wir den Kopf dieser Liste.

Und es in einem Spaß mit:

1> List=[{a,1},{b,2},{c,3}]. 
[{a,1},{b,2},{c,3}] 
2> F=fun(What, List) -> hd([ Value || {Key, Value} <- List, Key =:= What]) end. 
#Fun<erl_eval.12.82930912> 
3> F(c, List). 
3 
+0

Das sieht gut aus, aber ich habe noch eine dumme Frage ist dann: Was ist '=: ='? Warum ist '==' hier unerwünscht? – akalenuk

+0

Hallo! == kann verwendet werden, um Zahlen zu vergleichen, so dass 1.0 gleich 1 ist, aber in anderen Vergleichen sollten Sie den Vergleichsoperator "exact" verwenden, der =: = (und würde 1.0 von 1 abweichen), siehe: http://www.erlang.org/doc/reference_manual/expressions.html#id76768 – marcelog

+3

Dieser Ansatz ist gut für faulen Haskell, aber in Erlang wird es in jedem Fall die gesamte "Liste" durchqueren müssen, während "get_value/2" stoppt, wenn es gefunden wird das erste Spiel –

0
find(K, [H|T]) -> 
    case H of 
     {K, V} -> V; 
     _ -> find(K, T) 
    end; 
find(_, []) -> none. 
Verwandte Themen