2012-06-03 26 views
7

Tôi mới sử dụng Erlang và có thể tôi vừa bỏ qua vấn đề này trong hướng dẫn mặc dù nó không quan trọng. Giả sử, tôi có một danh sách các cặp {Key, Value} nhận được từ erlang: fun_info/1. Tôi muốn biết tính năng chức năng, phần còn lại của danh sách không quan tâm đến tôi. Vì vậy, tôi viết một cái gì đó như:Tìm một giá trị trong danh sách {key, value} trong Erlang

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

Và sau đó làm:

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

tôi hoạt động tốt, nhưng cái gì đó như find_value nên một thói quen quá phổ biến để viết nó? Tôi không thể tìm thấy 'tương tự trong BIF' mặc dù. Vì vậy, câu hỏi đặt ra là: nó có một cách tốt đẹp thanh lịch để có được một giá trị cho một khóa từ một danh sách các {key, value} tuple?

Trả lời

10

lists:keyfind/3 thực hiện việc này. Ở đây tôi đã ánh xạ nó vào giao diện find_value/2 của bạn:

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

proplists có thể là một con đường tốt hơn, mặc dù.

4

Kể từ danh sách: keyfind/3 đã được đăng, tôi sẽ đề cập đến một lựa chọn hữu ích, sử dụng danh sách comprehensions:

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

Điều này có nghĩa nhận được tất cả các giá trị như vậy mà mỗi phần tử là "giá trị gia tăng" và xuất phát từ một tuple khớp với {arity, Value} bên trong List. Vì danh sách hiểu được trả về một danh sách, chúng ta sẽ nhận được phần đầu của danh sách đó.

Và sử dụng nó trong một cách vui vẻ:

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

này sẽ rất tốt, nhưng tôi có một câu hỏi ngớ ngẩn sau đó: những gì là '=: ='? Tại sao '==' không mong muốn ở đây? – akalenuk

+0

Xin chào! == có thể được sử dụng để so sánh các con số, để 1.0 bằng 1, nhưng trong các so sánh khác, bạn nên sử dụng toán tử so sánh "chính xác", đó là =: = (và sẽ tạo 1.0 khác với 1), xem: http://www.erlang.org/doc/reference_manual/expressions.html#id76768 – marcelog

+3

Cách tiếp cận này là tốt cho Haskell lười biếng, nhưng trong Erlang nó sẽ phải đi qua toàn bộ 'List' trong mọi trường hợp trong khi' get_value/2' dừng lại khi nó tìm thấy trận đấu đầu tiên. –

2

proplists:get_value có phải là cách để làm điều đó nếu bạn không quan tâm về tốc độ

lists:keyfind Nó là sự lựa chọn tốt nhất cho hiệu suất kể từ khi là một BIF . Bạn có thể wrapit với một element/2 như thế này

element(2, lists:keyfind(K, 1, L)) 

Và bạn sẽ nhận được cùng một kết quả của proplists: get_value nhưng nhanh hơn.

Nguồn:http://www.ostinelli.net/erlang-listskeyfind-or-proplistsget_value/

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