Search code examples
arraysmatlabcell-array

Compare and find strings in 2 dimensional array


I am New to Matlab and I am stuck in efficiently solving the following problem.

I have two arrays (both of them 2D) and I want to check array1 col by col to know how many elements appear in each col of array2 (compare col to col)

for example

array1

    ---------
    'a1'  'b1'    'c1'   
    'd1'  'e1'    'f1'

array2
----------
    'a1'   'a1'   'b1'  'b1'  'a1' 
    'd1'   'd1'   'c1'  'd1'  'c1'
    'c1'   'c1'   'b1'  'd1'  'd1'

I am trying to get the following output

2 elements from array1 col1 appear in array2 col1
2 elements from array1 col1 appear in array2 col2
0 elements from array1 col1 appear in array2 col3
1 elements from array1 col1 appear in array2 col4
2 elements from array1 col1 appear in array2 col5

0 elements from array1 col2 appear in array2 col1
0 elements from array1 col2 appear in array2 col2
1 elements from array1 col2 appear in array2 col3
1 elements from array1 col2 appear in array2 col4
0 elements from array1 col2 appear in array2 col5

1 elements from array1 col3 appear in array2 col1
1 elements from array1 col3 appear in array2 col2
1 elements from array1 col3 appear in array2 col3
0 elements from array1 col3 appear in array2 col4
1 elements from array1 col3 appear in array2 col5
and so on

now I tried to do the below ugly code getting partial output

for i=1:size(Array1,2)
   for m=1:size(Array1,1)
     element = Array1(i,m);

     indx =find(ismember(Array2,element));
     Array_match(indx) = Array_match(indx) + 1;
     end
    for s=2:size(Array1,1)
    if  length(char(Array1(s,i))) > 0 
        tt= tt + 1;
    end
    length(Array_test_words(s,i))
    end
    Indx2 = find((Array_match) > tt);
 end

Solution

  • Apply unique to the concatenation of both arrays to transform the cells into numeric labels. Remove repeated values in each column of the second array. Then test for equality with bsxfun and aggregate results for each combination of columns:

    [~, ~, labels] = unique({array1{:} array2{:}});
    a1 = reshape(labels(1:numel(array1)),size(array1)); %// array1 as numeric labels
    a2 = reshape(labels(numel(array1)+1:end), size(array2)); %// same for array2
    a2 = sort(a2);
    a2(diff([NaN(1,size(a2,2)); a2])==0) = NaN; %// remove repeated values
    m = bsxfun(@eq, permute(a1, [1 3 2]), permute(a2, [3 1 4 2])); %// find matches
    result = squeeze(sum(reshape(m, [],size(a1,2),size(a2,2)), 1));
    

    In your rexample this gives

    result =
         2     2     0     1     2
         0     0     1     1     0
         1     1     1     0     1