tags:

views:

113

answers:

4

I have three 1-d arrays where elements are some values and I want to compare every element in one array to all elements in other two.

For example:

a=[2,4,6,8,12]
b=[1,3,5,9,10]
c=[3,5,8,11,15]

I want to know if there are same values in different arrays (in this case there are 3,5,8)

+1  A: 

Define what you mean by compare. If the arrays are of the same length, and you are comparing equality then you can just do foo == bar -- it's vectorized. If you need to compare in the less than/greater than sense, you can do sign(foo-bar). If the arrays are not the same length and/or you aren't comparing element-wise -- please clarify what you'd like the output of the comparison to be. For instance,

foo = 1:3;
bar = [1,2,4];
baz = 1:2;
sign(repmat(foo',1,length([bar,baz])) - repmat([bar, baz],length(foo),1))
# or, more concisely:
bsxfun(@(x,y)sign(x-y),foo',[bar,baz])

does what you ask for, but there is probably a better way depending on what you want as an output.

EDIT (OP clarified question): To find common elements in the 3 arrays, you can simply do:

>> [intersect(a,[b,c]), intersect(b,c)]
ans =
     8     3     5
Leo Alekseyev
arrays are of the same lenght,and foo==bar doesnt do what i want,it compares only elements wih same index,what i need is to compare each element from one array with each element in another two
sasha
In that case, to compare e.g. arrays foo and bar you do bsxfun(@eq,foo',bar) (or bsxfun(@(x,y)sign(x-y),foo',bar) -- this gives you a matrix where for row i, it compares ith element of foo to all elements of bar.
Leo Alekseyev
A: 

I do the example for two arrays. For three, you just do all the pairwise comparisons or you catenate.

%# make three arrays (they do not need to be equal length)
A = randi(25,10,1);
B = randi(30,10,1); 
%# if you have a third array C of, say, length 20, you can catenate with B
%# to create an array of total length 50 and do all the comparisons in one go.


%# to know which element of A is equal to which element in B, you do
equalityMatrix = bsxfun(@eq,A,B'); %'# replace @eq with @gt or @lt if you wonder about 
%# greater or smaller
%# the result is a 25-by-30 array, where equalityMatrix(i,j) is 1 if A(i) is equal to B(j)

EDIT: Leo Alekseyev has the correct answer to the clarified question: Use intersect twice.

Jonas
+3  A: 

Leo is almost right, should be

unique([intersect(a,[b,c]), intersect(b,c)])
AVB
+4  A: 

The answer given by AB is correct, but it is specific for the case when you have 3 arrays that you are comparing. There is another alternative that will easily scale to any number of arrays of arbitrary size. The only assumption is that each individual array contains unique (i.e. non-repeated) values:

>> allValues = sort([a(:); b(:); c(:)]);  %# Collect all of the arrays
>> repeatedValues = allValues(diff(allValues) == 0)  %# Find repeated values

repeatedValues =

     3
     5
     8

If the arrays contains repeated values, you will need to call UNIQUE on each of them before using the above solution.

gnovice