Erlang Central

Difference between revisions of "Finding Elements in One Array but Not Another"

From ErlangCentral Wiki

 
m (typo)
(2 intermediate revisions by 2 users not shown)
Line 7: Line 7:
 
You want to find elements in list A that aren't in list B. Erlang provides several ways of doing this:  
 
You want to find elements in list A that aren't in list B. Erlang provides several ways of doing this:  
  
Use the lists:subtract Function
+
Use lists:subtract/2 , or the equivalent -- operator.
  
The lists module provides the subtract function, which takes two list and returns a new copy of the first list, such that the first occurrence of each element of the second list is removed. For example:
 
 
<code>
 
<code>
1> A = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16].
+
1> A = lists:seq(1,16).
 
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
 
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
2> B = [2,4,6,8,9,10,12,14,15,16].
+
2> B = lists:seq(2,16,2).
[2,4,6,8,9,10,12,14,15,16].
+
[2,4,6,8,10,12,14,16].
 
3> lists:subtract(A,B).
 
3> lists:subtract(A,B).
[1,3,5,7,11,13]
+
[1,3,5,7,9,11,13,15]
</code>
+
 
+
Note: Erlang provides native list operators for concatentation (++) and subtraction (--). The subtraction operator provides the same functionality as the lists:subtract function:
+
<code>
+
 
4> A -- B.
 
4> A -- B.
[1,3,5,7,11,13]
+
[1,3,5,7,9,11,13,15]
 
</code>
 
</code>
  
 
Iterate over the two lists  
 
Iterate over the two lists  
  
You can iterate over the two lists (using the lists:foreach function), and filter out any entries from list A that are also members of list B.  
+
You can iterate over the two lists, and filter out any entries from list A that are also members of list B.  
 
<code>
 
<code>
5> lists:foldl(fun(X,ACC) -> Y=lists:member(X, B),
+
5> lists:foldr(fun(X,Acc) -> Y=lists:member(X, B),
5>    if Y -> [X|ACC];
+
5>    if Y -> [X|Acc];
 
5>    true -> ACC
 
5>    true -> ACC
5> end end, [], lists:reverse(A)).
+
5> end end, [], A).
[2,4,6,8,9,10,12,14,15,16]
+
[1,3,5,7,9,11,13,15]
 +
6> lists:filter(fun (X) -> not lists:member(X,B) end, A).
 +
[1,3,5,7,9,11,13,15]
 
</code>
 
</code>
  
  
[[Category:CookBook]]
+
[[Category:CookBook]][[Category:ListRecipes]]

Revision as of 15:01, 24 September 2006

Problem

You want to find elements that are in one list but not another.

Solution

You want to find elements in list A that aren't in list B. Erlang provides several ways of doing this:

Use lists:subtract/2 , or the equivalent -- operator.

1> A = lists:seq(1,16).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
2> B = lists:seq(2,16,2).
[2,4,6,8,10,12,14,16].
3> lists:subtract(A,B).
[1,3,5,7,9,11,13,15]
4> A -- B.
[1,3,5,7,9,11,13,15]

Iterate over the two lists

You can iterate over the two lists, and filter out any entries from list A that are also members of list B.

5> lists:foldr(fun(X,Acc) -> Y=lists:member(X, B),
5>    if Y -> [X|Acc];
5>    true -> ACC
5> end end, [], A).
[1,3,5,7,9,11,13,15]
6> lists:filter(fun (X) -> not lists:member(X,B) end, A).
[1,3,5,7,9,11,13,15]