4

如何在 Matlab 中找到以下两个数组结构的交集。

例如,我有两个结构数组ab

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)的元素都是结构。我该如何克服这个困难。谢谢。ab

4

3 回答 3

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);

或者,您是否考虑过用从句柄类派生的类对象替换您的结构?可能会重载类的关系运算符,然后应该可以直接对类对象进行排序(我没有仔细研究过这个解决方案——这只是我脑海中的一个提议)。

于 2013-05-29T05:33:43.750 回答
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);

这样您就不需要显式指定所有结构字段。当然,如果结构字段包含非数字值,这将不起作用。

任何类型和维度的字段的通用方法

如果您不确定存储在结构中的数据的类型和大小,请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)));
于 2013-05-29T11:04:41.787 回答
1

一种系统的方法是产生一个哈希- 然后使用 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
于 2013-05-29T11:49:41.333 回答