1 view (last 30 days)

Show older comments

I want to check that the contents of two arrays are equal, ignoring ordering of the elements.

I couldn't find an existing answer on this for some reason. There are two parts to this question, depending on whether the arrays are sets or not.

1. Checking equality for two sets

Assuming there are no duplicates I could use set operaions but it doesn't look like Matlab has sets, only set operations, and I couldn't find a setisequal function. Also, there are so many possible ways to do it I'm not sure which is the best:

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

assert(isequal(intersect(A, B), union(A, B)))

or

assert(isempty(setdiff(A,B)) & isempty(setdiff(B,A)))

or

assert(all(ismember(B, A)) & all(ismember(A, B)))

or

assert(isequal(unique(A), unique(B)))

However, if there may be different numbers of duplicates in either of the two arrays, then the above set operations will ignore them.

2. Checking equality for non-sets

This is the best I could think of in this case but it involves two sort operations which is quite inefficient:

assert(isequal(sort(A), sort(B)))

No doubt there is something very simple that I am missing here...

Walter Roberson
on 17 Oct 2021

%sets case

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

isequal(unique(A), unique(B))

For the sets case, a different approach just might be faster:

numel(A) == numel(B) && all(ismember(A, B))

%nonset case:

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

isequal(unique(A), unique(B))

Jan
on 17 Oct 2021

unique, setdiff, union and ismember call the function sort also internally. So

% assert(isequal(sort(A), sort(B)))

Is a very efficient solution.

A = randperm(1e6, 1e6);

B = randperm(1e6, 1e6);

tic

for k = 1:10

isequal(sort(A), sort(B));

end

toc

tic

for k = 1:10

all(ismembc(A, sort(B))); % Internal helper of ISMEMBER

end

toc

If repeated elements are existing:

A = randi([0,1e3], 1, 1e6);

B = randi([0,1e3], 1, 1e6);

tic

for k = 1:10

isequal(unique(A), unique(B));

end

toc

tic

for k = 1:10

numel(A) == numel(B) && all(ismember(A, B));

end

toc

tic

for k = 1:10

As = sort(A);

Au = As([true, diff(As) ~= 0]); % Remove repeated elements

Bs = sort(B);

Bu = Bs([true, diff(Bs) ~= 0]); % Remove repeated elements

isequal(Au, Bu);

end

toc

In R2018b the last method is faster than isequal(unique(A), unique(B)). Try this locally.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!