# Finding correct row in array with multiple columns matching different conditions

32 views (last 30 days)
Avinash Rajendra on 25 Apr 2021
Commented: DGM on 25 Apr 2021
I have the following example and want to find the correct row. I have a for loop that does the job, but need an alternative solution for performance and efficiency reasons. Any help will be appreciated. Thanks in advance!
A = [1 2 3;
4 5 6]; % 2 rows and 3 columns
B = [1 1 2;
1 2 3;
2 2 4;
3 4 5;
4 5 6]; % 5 rows and 3 columns
What I need is the row in B where all the values of the row are respectively equal to the values of one subject row in A. In the example, all the values of the second row of B match all the values of the first row of A, and similarly with the fifth row of B and the second row of A. So, my output should be [2; 5]. One point to note is that there will only be one row in B where all its values will match those of the subject row in A.
My for loop works like this:
indices = ones(size(A, 1), 1); %size of indices = 2 rows and 1 column
for k = 1:size(A, 1) %k will go from 1 to 2; k defines subject row
C = A(k, 1:end); % C = [1 2 3] for k = 1, C = [4 5 6] for k = 2
D = find(B(1:end, 1) == C(1); % 1 and 2 for k = 1, 5 for k = 2
E = find(B(1:end, 2) == C(2); % 2 and 3, 5 for k = 2
F = find(B(1:end, 3) == C(3); % 2 for k = 1, 5 for k = 2
indices(k, 1) = intersect(intersect(D, E), F); % 2 for k = 1, 5 for k = 2
end

DGM on 25 Apr 2021
Edited: DGM on 25 Apr 2021
Maybe something like this:
A = [1 2 3; 4 5 6]; % 2 rows and 3 columns
B = [1 1 2; 1 2 3; 2 2 4; 3 4 5; 4 5 6]; % 5 rows and 3 columns
% this is a logical index of the rows which match
C = any(all(bsxfun(@eq,B,permute(A,[3 2 1])),2),3)
gives
C =
5×1 logical array
0
1
0
0
1
For most indexing purposes, this may suffice. If you really need the list of row subscripts, just do
C = find(C)
##### 2 CommentsShowHide 1 older comment
DGM on 25 Apr 2021
For what it's worth, I consider ismember() a matter of convenience. It gives the correct answers and the syntax is simple, but if speed is of value, there are usually better options. On my system, in either R2015b or R2019b, this:
C = ismember(B,A,'rows');
takes about 13-14 times as long as this convoluted mess:
C = any(all(bsxfun(@eq,B,permute(A,[3 2 1])),2),3);
Your case likely doesn't need the speed, but it's good to be aware of the penalties so that you can make the judgement when it does matter.

### More Answers (1)

the cyclist on 25 Apr 2021
A = [1 2 3;
4 5 6]; % 2 rows and 3 columns
B = [1 1 2;
1 2 3;
2 2 4;
3 4 5;
4 5 6]; % 5 rows and 3 columns
indices = find(ismember(B,A,'rows'))
indices = 2×1
2 5