4

Matlab で次の 2 つの配列構造体の交点を見つけるにはどうすればよいですか。

たとえば、2 つの構造体配列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

体系的なアプローチは、ハッシュを生成し、次に交差を使用することです。

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 に答える