iT邦幫忙

DAY 9
1

蠻可愛的 Erlang 與 Elixir系列 第 9

List comprehension與守衛(Guard)

  • 分享至 

  • xImage
  •  

在erlang中,List操作在前面的例子中,已經多次使用.
接著來看看List comprehension,目前尚未看到有合適的中文翻譯,
故在此均保留使用英文.
直接看例子就能理解了.

1> L = [1,2,3,4,5].
[1,2,3,4,5]
2> lists:map(fun(X) -> 2 * X end, L).
[2,4,6,8,10]
3> [2 * X || X <- L].
[2,4,6,8,10]

第2是使用lists:map()函式來處理,第3就是使用List comprehension,
相對簡明.

接著來看一下應用,我們來算畢達哥拉斯組數.

-module(p1009).
-export([pythag/1]).

pythag(N) ->
  [ {A, B, C} ||
      A <- lists:seq(1,N),
      B <- lists:seq(1,N),
      C <- lists:seq(1,N),
      A+B+C =< N,
      A*A + B*B =:= C*C
  ].

編譯及執行:
4> c("p1009").
{ok,p1009}
5> p1009:pythag(30).
[{3,4,5},{4,3,5},{5,12,13},{6,8,10},{8,6,10},{12,5,13}]

上面的程式運用了lists:seq()來產生序列數字;
=:= 用來判斷是否相等,與一般程式語言的 ==, 符號略有差異.
其實就把畢達哥拉斯組數的數學公式放進去,也不必像一般程式
語言那樣要寫三重迴圈,再加邏輯判斷.

接著來介紹守衛(Guard),守衛可以用來增強模式比對.
例如要寫一個max(X,Y)的函數.就可以利用守衛.
我們把上面程式增加max()的定義,增加-export部份的內容.

-module(p1009).
-export([pythag/1,max/2]).
%%%               ^^^^^^
%%%             Add this
pythag(N) ->
  [ {A, B, C} ||
      A <- lists:seq(1,N),
      B <- lists:seq(1,N),
      C <- lists:seq(1,N),
      A+B+C =< N,
      A*A + B*B =:= C*C
  ].

%%% Apped here
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.

max()函數很簡單,就不附操作情況.
注意到上面的 % ,這是erlang註解用的符號;
慣例上,程式前面的註解,用來說明程式的功能
等meta data,會用%% 開頭.

守衛還有以下的守衛函數可以搭配使用.

is_atom(X) 
is_binary(X) 
is_constant(X) 
is_float(X) 
is_function(X) 
is_function(X, N)
is_integer(X) 
is_list(X) 
is_map(X) 
is_number(X) 
is_pid(X) 
is_pmod(X) 
is_port(X) 
is_reference(X) 
is_tuple(X) 
is_record(X,Tag) 
is_record(X,Tag,N) 

上一篇
是遞迴,我加了遞迴.
下一篇
邏輯判斷式 case 與 if
系列文
蠻可愛的 Erlang 與 Elixir30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言