如何在Matlab中找到以下两个数组结构的交集。
例如,我有两个结构数组a
和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);
我希望找到a
和b
的交集如下:
c = intersect(a,b)
c
应该
c = struct('x',1,'y',1);
但是当我输入intersect(a,b)
时似乎错了,因为a
和b
的元素都是结构。我怎样才能解决这个难题。感谢。
答案 0 :(得分:4)
优雅的解决方案是为intersect
提供一个比较运算符(例如,C++)。
不幸的是,Matlab似乎并不支持这种功能/灵活性。
您的问题的解决方法是
% 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);
或者,您是否考虑使用从句柄类派生的类对象替换结构?有可能重载类的relational operators,然后应该可以直接对类对象进行排序(我没有仔细研究过这个解决方案 - 这只是我头脑中的一个提议)。
答案 1 :(得分:4)
Shai方法的一般变体是:
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);
这样您就不需要显式指定所有结构域。当然,如果struct字段包含非数字值,这将不起作用。
如果您不确定结构中存储的数据的类型和大小,interesect
将不会删除它。相反,您必须使用isequal
循环。我在这里使用arrayfun
来获得优雅:
[X, Y] = meshgrid(1:numel(a), 1:numel(b));
c = a(any(arrayfun(@(m, n)isequal(a(m), b(n)), X, Y)));
答案 2 :(得分:1)
系统方法是产生hash - 然后使用intersect:
hash_fun = @(x) sprintf('x:%g;y:%g',x.x,x.y);
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