列表操作在Erlang中很常用,lists模塊提供了很多函數來處理列表,這些的函數處理的列表對象通常分為兩類,一類是通用的,如[1,2,a,bc,{key, value}],列表元素沒有明顯的”結構“;還有一類就是針對key-value結構的函數(tuple-list),即列表每個元素都是{key, value}結構,整個列表看起來是[{key1,value1},{key2,value2},…],類似一種散列,下面我就以列表的數據結構來分類整理一下列表函數。

通用型函數

1、檢測列表元素

all(Pred, List) -> boolean();

any(Pred, List) -> boolean();

all/2 Pred是一個斷言函數,即返回的是布爾值,列表裡面所有元素作為參數分別傳遞給Pred,只有全部都為true時,整個表達式的值才為true,否則為false。可以將all/2看成是邏輯與。

any/2 只要列表中有一個元素的Pred返回為true,整個表達式的值就為true,否則為false。可以將any/2看出邏輯或。

eg:

 
  
  1. 1> Pred = fun(Elem) -> is_integer(Elem) end
  2. #Fun<erl_eval.6.82930912> 
  3. 2> lists:all(Pred, [1,2,a,4]). 
  4. false 
  5. 3> lists:all(Pred, [1,2,3.1,4]). 
  6. false 
  7. 4> lists:all(Pred, [1,2,3,4]).   
  8. true 
  9. 10> Pred = fun(Elem) -> is_integer(Elem) end
  10. #Fun<erl_eval.6.82930912> 
  11. 11> lists:any(Pred, [1,a]).                   
  12. true 
  13. 12> lists:any(Pred, [a,b]). 
  14. false 

2、元素連接

append(ListOfLists) -> List1;

append(List1, List2) -> List3;

concat(Things) -> string();

flatten(DeepList) -> List;

append/1將一個由列表構成的列表降低列表維數;

append/2將List2追加到List1後面,返回這個新的列表;

concat/1將一個列表連接為一個字符串

flatten/1將一個多維列表降低一維,不是列表的元素不會被處理(這個很少使用)

eg:

 
  
  1. 14> lists:append([[a],[b,c]]). 
  2. [a,b,c] 
  3. 15> lists:append([1,2,3], [a,b,c]). 
  4. [1,2,3,a,b,c] 
  5. 16> lists:concat(['usr''/''lib']). 
  6. "usr/lib" 
  7. 19> lists:flatten([[a],[b]]). 
  8. [a,b] 
  9. 20> lists:flatten([[a],b]).            
  10. [a,b] 

3、刪除,過濾列表元素

delete(Elem, List1) -> List2;

dropwhile(Pred, List1) -> List2;

filter(Pred, List1) -> List2;

delete/2 從List1中刪除元素第一個Elem元素,返回刪除之後的列表,如果沒有這個元素的話,返回的新列表和List1是一樣的。

dropwhile/2 將List1中的元素作為參數傳遞給Pred,當Pred返回true時就把這個元素刪除,這樣就把想要刪除的元素從List1中全部刪除了,返回一個新列表List2。

filter/2 和dropwhile相反,返回true的就保留,返回false的全部刪除過濾掉。

eg:

 
  
  1. 42> L = [1,2,a,b,c].             
  2. [1,2,a,b,c] 
  3. 43> F = fun(E) -> is_integer(E) end
  4. #Fun<erl_eval.6.82930912> 
  5. 44> lists:filter(F, L). 
  6. [1,2] 
  7. 47> lists:dropwhile(F, L).  
  8. [a,b,c] 

4、扁平化操

foldl(Fun, Acc0, List) -> Acc1

foldr(Fun, Acc0, List) -> Acc1

flodl/2 從列表的最左邊開始進行扁平化處理,foldr/2 從最右邊開始處理,開銷交大

eg:

 
  
  1. > lists:foldl(fun(X, Sum) -> X + Sum end, 0, [1,2,3,4,5]). 
  2. 15 

5、全列表處理(常用)

foreach(Fun, List) -> ok

map(Fun, List1) -> List2

foreach/2 列表中的每個元素作為參數,執行一次Fun函數,不要返回值!

map/2 列表中的每個元素作為參數,執行一次Fun函數,要返回值!

eg:

 
  
  1. 29> Fun = fun(Id) -> io:format("~w", [Id]), Id*Id end
  2. #Fun<erl_eval.6.82930912> 
  3. 30> lists:foreach(Fun, lists:seq(1,10)).               
  4. 12345678910ok 
  5. 31> lists:map(Fun, lists:seq(1,10)).     
  6. 12345678910[1,4,9,16,25,36,49,64,81,100] 

6、分片

sublist(List1, Len) -> List2;

sublist(List1, Start, Len) -> List2;

partition(Pred, List) -> {Satisfying, NotSatisfying};

sublist/2 從List1開始位置,返回一個長度為Len的列表

sublist/3 從指定位置開始,返回一個長度為Len的列表

partition/2 返回一個tuple,第一部分是Pred返回true的元素構成的列表,第二部分是false構成的列表

eg:

 
  
  1. eg: 
  2. 42> L = [1,2,a,b,c].             
  3. [1,2,a,b,c] 
  4. 43> F = fun(E) -> is_integer(E) end
  5. 48> lists:sublist(L, 2, 2). 
  6. [2,a] 
  7. 49> lists:partition(F, L). 
  8. {[1,2],[a,b,c]} 

針對tuple-list的函數

1、根據Key來刪除列表元素

keydelete(Key, N, TupleList1) -> TupleList2   N是Key的位置

eg:

 
  
  1. 35> L = [{name, <<"shicheng">>}, {id, 1234}, {type, 1}]. 
  2. [{name,<<"shicheng">>},{id,1234},{type,1}] 
  3. 36> lists:keydelete(id, 1, L). 
  4. [{name,<<"shicheng">>},{type,1}] 

2、替換一個元素

keyreplace(Key, N, TupleList1, NewTuple) -> TupleList2

eg:

 
  
  1. 37> lists:keyreplace(id, 1, L, {id, 668}). 
  2. [{name,<<"shicheng">>},{id,668},{type,1}] 

3、按照指定key進行排序,最常見的是對一個數值型的值進行排列

keysort(N, TupleList1) -> TupleList2

eg:

 
  
  1. 39> L = [{id, 10},{type, 5}]. 
  2. [{id,10},{type,5}] 
  3. 40> lists:keysort(2, L). 
  4. [{type,5},{id,10}] 

   還有好幾個方法,不過都是很簡單的,比如sort/1,max/1, min/1, nth/2, reverse/1等到,根據函數名字就可以知道用途和用法了。在開發過程中,處理列表這類數據結構首選lists提供的標準方法。