24

フィールド名が異なる 2 つの構造を結合したいと考えています。

たとえば、次のように開始します。

A.field1 = 1;
A.field2 = 'a';

B.field3 = 2;
B.field4 = 'b';

私はを頂きたい:

C.field1 = 1;
C.field2 = 'a';
C.field3 = 2;
C.field4 = 'b';

「フィールド名」と for ループを使用するよりも効率的な方法はありますか?

編集:フィールド名が競合する場合、 を優先すると仮定しましょうA

4

5 に答える 5

19

衝突なしで、あなたはすることができます

M = [fieldnames(A)' fieldnames(B)'; struct2cell(A)' struct2cell(B)'];
C=struct(M{:});

そして、これはかなり効率的です。ただし、structフィールド名が重複しているとエラーが発生し、使用してそれらを事前にチェックすると、uniqueパフォーマンスが低下し、ループが改善されます。しかし、これは次のようになります。

M = [fieldnames(A)' fieldnames(B)'; struct2cell(A)' struct2cell(B)'];

[tmp, rows] = unique(M(1,:), 'last');
M=M(:, rows);

C=struct(M{:});

競合がないと仮定し、呼び出しの周りで try/catch を使用しstructて競合処理ケースに適切に分解することで、ハイブリッド ソリューションを作成できる場合があります。

于 2008-09-02T14:36:20.563 に答える
4

ループを使用して競合をうまく処理できるとは思いませんし、回避する必要もないと思います。(ただし、効率は多くの分野で問題になる可能性があると思います...)

私は数年前に書いた と呼ばれる関数を使用しますsetdefaults.m。これは、ある構造体と別の構造体の値を結合し、競合が発生した場合に一方が他方よりも優先されるようにします。

% SETDEFAULTS sets the default structure values 
%    SOUT = SETDEFAULTS(S, SDEF) reproduces in S 
%    all the structure fields, and their values,  that exist in 
%    SDEF that do not exist in S. 
%    SOUT = SETDEFAULTS(S, SDEF, OVERRIDE) does
%    the same function as above, but if OVERRIDE is 1,
%    it copies all fields of SDEF to SOUT.

function sout = setdefaults(s,sdef,override)
if (not(exist('override','var')))
    override = 0;
end

sout = s;
for f = fieldnames(sdef)'
    cf = char(f);
    if (override | not(isfield(sout,cf)))
        sout = setfield(sout,cf,getfield(sdef,cf));
    end
end

今考えてみると、「オーバーライド」入力は不要であると確信しています (入力の順序を切り替えることができます) が、100% 確信があるわけではありません. setdefaults2.m):

% SETDEFAULTS2 sets the default structure values 
%    SOUT = SETDEFAULTS(S, SDEF) reproduces in S 
%    all the structure fields, and their values,  that exist in 
%    SDEF that do not exist in S. 

function sout = setdefaults2(s,sdef)
sout = sdef;
for f = fieldnames(s)'
    sout = setfield(sout,f{1},getfield(s,f{1}));
end

そしてそれをテストするためのいくつかのサンプル:

>> S1 = struct('a',1,'b',2,'c',3);
>> S2 = struct('b',4,'c',5,'d',6);
>> setdefaults2(S1,S2)

ans = 

    b: 2
    c: 3
    d: 6
    a: 1

>> setdefaults2(S2,S1)

ans = 

    a: 1
    b: 4
    c: 5
    d: 6
于 2008-12-10T19:58:09.630 に答える
2

C では、構造体はそのメンバーの 1 つとして別の構造体を持つことができます。これはあなたが求めているものとまったく同じではありませんが、1 つの構造体に別の構造体が含まれているか、1 つの構造体に 2 つの構造体が含まれており、どちらも必要な情報の一部を保持しているという状況になる可能性があります。

疑似コード: 実際の構文を覚えていません。

A.field1 = 1;
A.field2 = 'a';
A.field3 = struct B;

アクセスするには: A.field3.field4;

またはそのようなもの。

または、構造体 C に A と B の両方を保持させることもできます。

C.A = struct A;
C.B = struct B;

アクセスすると、次のようなもの

C.A.field1;
C.A.field2;
C.B.field3;
C.B.field4;

お役に立てれば!

編集:これらのソリューションは両方とも、名前の衝突を回避します。

また、私はあなたのmatlabタグを見ませんでした。慣例により、質問を編集してその情報を含める必要があります。

于 2008-09-02T00:43:10.583 に答える