MATLAB: Search nx3 array row-wise for 2 equal elements

arraymatching elementsearch

I have a nx3 sized array. I need to find all rows that have 2 common elements. I can do this using logical operators and comparing each element in turn, but this seems very inefficient.
Is there a better solution?
For example
In the following array, I need to identify that rows 1 and 3 contain 2 matching elements (as do rows 2 and 4).
[5 6 2,
3 2 7,
4 6 5,
9 7 2,
5 3 8]

Best Answer

My initial idea is below, but someone may be able to improve on it in efficiency or elegance.
There is an awkwardness in this solution: if row A has two elements in common with both rows B and C, then the results may contain both [A B C] and [B C]. There are various things you could do about this - but a more precise specification of the problem is needed in order to choose how to handle such cases. If the data only ever has pairs of matching rows, there's no problem.
% data
a = [5 6 2;
3 2 7;
4 6 5;
9 7 2;
5 3 8]
% code
ap = a.';
groups = cell(1, size(ap,2)-1); % pre-allocate cell array for results
ngroups = 0;
for k = 1:size(ap, 2)-1 % loop over rows of a (cols of ap)
same = bsxfun(@ismember, ap(:,k), ap(:,k+1:end)); % find common elements
matches = find(sum(same) >= 2); % find cols of ap with at least 2 such
if ~isempty(matches) % at least one col has 2 matches
ngroups = ngroups+1; % so add it to the result
groups{ngroups} = [k k+matches];
end
end
groups = groups(1:ngroups); % trim results to the part that was used