2012-06-03 23 views
7

Soy nuevo en Erlang y tal vez me perdí este problema en el tutorial aunque es trivial. Digamos que tengo una lista de pares de {Key, Value} obtenidos de erlang: fun_info/1. Quiero saber la validez de la función, el resto de la lista no me interesa. Así que escribir algo como:Encontrar un valor en la lista de {clave, valor} en Erlang

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

y luego hacer:

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

que trabaja muy bien, pero debería ser algo así como find_value una rutina muy común que escribirlo? Sin embargo, no pude encontrar su 'análogo en BIFs'. Entonces, la pregunta es: ¿existe una forma agradable y elegante de obtener un valor para una clave de una lista de tuplas {clave, valor}?

Respuesta

10

lists:keyfind/3 hace esto. Aquí he mapeado en la interfaz de find_value/2:

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

proplists puede haber una ruta aún mejor, sin embargo.

4

Desde listas: keyfind/3 ya fue publicada, voy a mencionar otra opción útil, el uso de listas por comprensión:

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

Esto significa conseguir todos los valores de tal manera que cada elemento es "Valor" y viene de una tupla que coincide con {arity, Value} dentro de List. Dado que una lista de comprensión devuelve una lista, obtenemos el encabezado de esa lista.

Y su uso de una manera divertida:

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

Esto se ve muy bien, pero tengo otra pregunta tonta entonces: lo que es '=: ='? ¿Por qué '==' no es deseado aquí? – akalenuk

+0

¡Hola! == puede usarse para comparar números, de modo que 1.0 es igual a 1, pero en otras comparaciones, debe usar el operador de comparación "exacto", que es =: = (y haría 1.0 diferente de 1), consulte: http://www.erlang.org/doc/reference_manual/expressions.html#id76768 – marcelog

+3

Este enfoque es bueno para Haskell perezoso, pero en Erlang tendrá que recorrer toda la 'Lista' en cualquier caso, mientras' get_value/2' se detiene cuando lo encuentra el primer partido –

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