문제

필드 이름이 다른 두 구조를 결합하고 싶습니다.

예를 들어 다음으로 시작합니다.

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.

도움이 되었습니까?

해결책

충돌없이 할 수 있습니다

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 충돌 처리 사례로 우아하게 저하됩니다.

다른 팁

짧은 답변: setstructfields (Signal Process Toolbox가 있는 경우)


공식 솔루션은 Loren Shure가 게시했습니다. 그녀의 MathWorks 블로그, 그리고 다음에 의해 시연되었습니다. SC프랑스어는 여기 그리고 다른 질문에 대한 Eitan T의 답변.그러나 신호 처리 도구 상자가 있는 경우 문서화되지 않은 간단한 함수가 이미 이 작업을 수행합니다. setstructfields.

help setstructfields

 setstructfields Set fields of a structure using another structure
    setstructfields(STRUCTIN, NEWFIELDS) Set fields of STRUCTIN using
    another structure NEWFIELDS fields.  If fields exist in STRUCTIN
    but not in NEWFIELDS, they will not be changed.

내부적으로는 fieldnames 그리고 for 루프이므로 그 자체가 구조체인 필드에 대한 오류 검사 및 재귀 기능을 갖춘 편리한 함수입니다.

"원래" 구조체:

% struct with fields 'color' and 'count'
s = struct('color','orange','count',2)

s = 
    color: 'orange'
    count: 2

에 대한 새 값을 포함하는 두 번째 구조체 'count', 그리고 새로운 필드, 'shape':

% struct with fields 'count' and 'shape'
s2 = struct('count',4,'shape','round')

s2 = 
    count: 4
    shape: 'round'

부름 setstructfields:

>> s = setstructfields(s,s2)
s = 
    color: 'orange'
    count: 4
    shape: 'round'

필드 'count' ~이다 업데이트됨.필드 'shape' ~이다 추가됨.필드 'color' 변함없이 남아있다.

메모:이 기능은 문서화되지 않았으므로 언제든지 변경되거나 제거될 수 있습니다.

나는 좋은 것을 발견했다 파일 교환 솔루션:고양이를 구조하다.

성능을 테스트하지 않고도 내가 원하는 대로 정확하게 작동했다고 말할 수 있습니다.물론 중복 필드를 처리할 수도 있습니다.

작동 방식은 다음과 같습니다.

a.f1 = 1;
a.f2 = 2;
b.f2 = 3;
b.f4 = 4;

s = catstruct(a,b)

줄게

s = 

    f1: 1
    f2: 3
    f3: 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

C에서 구조체는 멤버 중 하나로 다른 구조체를 가질 수 있습니다.이것이 요청하는 것과 정확히 동일하지는 않지만 하나의 구조체에 다른 구조체가 포함되거나 하나의 구조체에 두 개의 구조체가 포함되어 있는 상황이 발생할 수 있습니다. 두 구조체 모두 원하는 정보의 일부를 보유하고 있습니다.

유사 코드:실제 구문이 기억나지 않습니다.

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

액세스:A.필드3.필드4;

또는 그런 종류의 것.

또는 구조체 C가 A와 B를 모두 보유하도록 할 수도 있습니다.

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

액세스 권한이 있으면 다음과 같습니다.

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

도움이 되었기를 바랍니다!

편집하다:이 두 가지 솔루션 모두 이름 충돌을 방지합니다.

게다가 난 당신을 보지 못했어요 matlab 꼬리표.관례적으로 해당 정보를 포함하도록 질문을 편집해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top