stdavid
stdavid

Reputation: 53

How to remove elements of one array from another?

I have two arrays:

A=[1 1 2 2 3 3 3];
B=[1 3];

Is there any function that can remove elements which are contained in B from A?

The result should be

C=[1 2 2 3 3];

The order is not important, but if there is more specific elements like two times 1 in A, then I need operation that removes (from A) only as many of these specific elements is in B (in this case only one of 1 and one of 3; meaning other 1 and 3 should remain in final product C). This function should be analogous to setdiff, with the difference that it should take care of multiple instances of array elements. This analogy can hold because my B only contains elements that are in A.

Upvotes: 4

Views: 871

Answers (2)

gnovice
gnovice

Reputation: 125864

Here's a vectorized solution using accumarray and repelem:

maxValue = max([A B]);
counts = accumarray(A(:), 1, [maxValue 1])-accumarray(B(:), 1, [maxValue 1]);
C = repelem(1:maxValue, max(counts, 0));

And the result for your sample data A = [1 1 2 2 3 3 3]; B = [1 3];:

C =

     1     2     2     3     3

This will even work for cases where there are values in B not in A (like B = [1 4];) or more of a given value in B than in A (like B = [1 1 1];).

Note: The above works sinceA and B contain integers. If they were to contain floating-point values, you could map the unique values to integers first using unique and ismember. Let's say we had the following sample data:

A = [0 0 pi pi 2*pi 2*pi 2*pi];
B = [0 2*pi];

Here's a variant of the above code that can handle this:

uniqueValues = unique([A B]);
[~, A] = ismember(A, uniqueValues);
[~, B] = ismember(B, uniqueValues);
maxValue = max([A B]);
counts = accumarray(A(:), 1, [maxValue 1])-accumarray(B(:), 1, [maxValue 1]);
C = uniqueValues(repelem(1:maxValue, max(counts, 0)));

And the results:

C =

         0    3.1416    3.1416    6.2832    6.2832  % [0 pi pi 2*pi 2*pi]

Upvotes: 1

Dan
Dan

Reputation: 45752

For loop solution:

C = A;    
for ii = 1:length(B)       
   C(find(C == B(ii), 1,'first')) = [];
end

Result

C =

     1     2     2     3     3

Upvotes: 4

Related Questions