Find the intersection of two array structures in Matlab

How to find the next intersection of two array structures in Matlab.

For example, I have two arrays struct a and b :

 a(1)=struct('x',1,'y',1); a(2)=struct('x',3,'y',2); a(3)=struct('x',4,'y',3); a(4)=struct('x',5,'y',4); a(5)=struct('x',1,'y',5); b(1)=struct('x',1,'y',1); b(2)=struct('x',3,'y',5); 

I want to find the intersection of a and b as follows:

 c = intersect(a,b) 

where c should be

 c = struct('x',1,'y',1); 

But when it seems wrong, when I type intersect(a,b) , since the elements a and b are both structures. How can I deal with this difficulty. Thanks.

+4
source share
3 answers

An elegant solution would be to supply intersect a comparator operator (e.g. C ++ ).
Unfortunately, Matlab does not seem to support such functionality / flexibility.

A workaround for your problem would be

 % convert structs into matrices A = [[a(:).x];[a(:).y]]'; B = [[b(:).x];[b(:).y]]'; % intersect the equivalent representation [C, ia, ib] = intersect( A, B, 'rows' ); % map back to original structs c = a(ia); 

Alternatively, do you consider replacing your structures with class objects derived from the handle class? Perhaps you can overload the relational operators of the class, and then it should be possible to sort the objects of the class directly (I don't look closely at this solution - it's just a sentence from the tip of my head).

+4
source

A more general version of Shay's approach:

 A = cell2mat(permute(struct2cell(a), [3 1 2])); B = cell2mat(permute(struct2cell(b), [3 1 2])); [C, ia] = intersect(A, B, 'rows'); c = a(ia); 

Thus, you do not need to explicitly specify all fields of the structure. Of course, this will not work if the string fields contain non-numeric values.

Generalized approach for fields of any type and size

If you are not sure about the type and size of the data stored in your structures, interesect will not crop it. Instead, you have to use isequal with a loop. I use arrayfun here for elegance:

 [X, Y] = meshgrid(1:numel(a), 1:numel(b)); c = a(any(arrayfun(@(m, n)isequal(a(m), b(n)), X, Y))); 
+4
source

A system approach would be to create hash - and then use intersect:

 hash_fun = @(x) sprintf('x:%g;y:%g',xx,xy); ha = arrayfun(hash_fun,a,'UniformOutput',false); hb = arrayfun(hash_fun,b,'UniformOutput',false); [hi,ind_a,ind_b]=intersect(ha,hb) res=a(ind_a) % result of intersection 
+1
source

Source: https://habr.com/ru/post/1483282/


All Articles