user5916581
user5916581

Reputation: 87

Matlab: searching arrays for similar values and create a new array containing all values

I have three column vectors:

A = [1;2;5;9;15]
B = [2;3;5;11;15]
C = [5;7;11;20;25]

I want to create a new column vector D by searching through all the elements of A B C, finding all the values and avoid repeating them in D.

I want D to be:

D = 
    1
    2
    3
    5
    7
    9
    11
    15
    20
    25

How to do this?
Thanks!

Upvotes: 1

Views: 132

Answers (3)

EBH
EBH

Reputation: 10450

Here is another (super-fast) way, not using unique, and no loops, if you are dealing only with integers:

A = [1;2;5;9;15];
B = [2;3;5;11;15];
C = [5;7;11;20;25];
tmp = [A;B;C]; % concat the vectors
R = min(tmp):max(tmp)+1; % the range of the values
ind = histcounts(tmp,R)>0; % find all elements within tmp
D = R(ind).' % extract the relevant values

This method could be generalized for doubles:

A = [1.2;2.62;5.74;9.29;15.31];
B = [2.3;3;5;9.29;15.31];
C = [1.2;2.62;11;20;25];
tmp = sort([A;B;C]); % concat and sort the vectors
R = [tmp; max(tmp)+1]; % the range of the values
ind = histcounts(tmp,R)>0; % find all elements within tmp
D = tmp(ind) % extract the relevant values

However, the need to sort the values first (in tmp) makes it slower than the other methods.

Upvotes: 3

patrik
patrik

Reputation: 4558

It is possible to sort the data and check the the unique values. This seems to be about as efficient as using the function unique(). Possibly with an advantage for using sort() and diff(). This may however be dependent on hardware and the difference is fairly insignificant, taking into account the simplicity of D = unique([A;B;C]);.

function test()

% A=[1;2;5;9;15];
% B=[2;3;5;11;15];
% C=[5;7;11;20;25];

A = 500*rand(10000000,1);
B= 500*rand(10000000,1);
C = 500*rand(10000000,1);

f1 = @() testA(A,B,C);
f2 = @() testB(A,B,C);

time1 = timeit(f1,1);
time2 = timeit(f2,1);
disp(time1);
disp(time2);

function D = testA(A,B,C)
d = sort([A;B;C]);
idx = diff(d);
D = d([1;idx]>0);

function D = testB(A,B,C)
D = unique([A;B;C]);

test

1.9085

1.9968

Upvotes: 1

deanshanahan
deanshanahan

Reputation: 320

This code should do what you want:

% Your sample arrays
A=[1;2;5;9;15]
B=[2;3;5;11;15]
C=[5;7;11;20;25]

% [A,B,C] concatenates the arrays to one single array
% Unique finds unqiues values in the input array
[D, IA, ID] = unique([A,B,C]);

disp(D);

% D = array with unique values

% ID = array with unique natural number assigned to equal values for the
% original array

% IA = array that can be referenced against ID to find the value in the
% original array

% ID and IA can be used to recreate the original array

Solution without using "unique", this is probably less efficient:

% SOLUTION WITHOUT USING UNIQUE

% Your variables
A=[1;2;5;9;15];
B=[2;3;5;11;15];
C=[5;7;11;20;25];

% Allocate a temporary array with your arrays concatenated
temp = sort([A;B;C]);
rep_count = 0; % Count number of repeat values

% Allocate a blank array for your output
D = zeros(length(temp),1);
D(1) = temp(1); % Initialise first element (is always unique)

% Iterate through temp and output unqiue values to D
for i = 2:length(temp)
    if (temp(i) == D(i-1-rep_count))
        rep_count = rep_count+1;
    else
        D(i-rep_count) =  temp(i);
    end
end

% Remove zeros at the end of D
D = D(1:length(D)-rep_count);

disp(D)

Upvotes: 1

Related Questions