xlabel matlab merge structure field

xlabel - ¿Cuáles son algunas formas eficientes de combinar dos estructuras en MATLAB?



title matlab (5)

En C, una estructura puede tener otra estructura como uno de sus miembros. Si bien esto no es exactamente lo mismo que lo que estás preguntando, puedes terminar con una situación en la que una estructura contiene otra, o una estructura contiene dos estructuras, que contienen partes de la información que deseas.

psuedocode: no recuerdo la sintaxis real.

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

para acceder: A.field3.field4;

O algo por el estilo.

O podrías tener struct C contener una A y una B:

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

con acceso a continuación, algo así como

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

¡espero que esto ayude!

EDITAR: ambas soluciones evitan nombrar colisiones.

Además, no vi tu etiqueta de matlab . Por convención, debería querer editar la pregunta para incluir esa información.

Quiero combinar dos estructuras con diferentes nombres de campos.

Por ejemplo, comenzando con:

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

Me gustaría tener:

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

¿Hay una forma más eficiente que usar "nombres de campo" y un bucle for?

EDITAR: Supongamos que en el caso de conflictos de nombre de campo damos preferencia a A


He encontrado una buena solución en File Exchange: catstruct .

Sin probar el rendimiento, puedo decir que hizo exactamente lo que yo quería. Puede tratar con campos duplicados, por supuesto.

Así es como funciona:

a.f1 = 1; a.f2 = 2; b.f2 = 3; b.f4 = 4; s = catstruct(a,b)

Daré

s = f1: 1 f2: 3 f3: 4


No creo que puedas manejar bien los conflictos sin un bucle, ni creo que necesites evitar uno. (Aunque supongo que la eficiencia podría ser un problema con muchos campos ...)

Utilizo una función que escribí hace unos años llamada setdefaults.m , que combina una estructura con los valores de otra estructura, donde uno tiene prioridad sobre el otro en caso de conflicto.

% 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

Ahora que lo pienso, estoy bastante seguro de que la entrada de "anulación" es innecesaria (puedes cambiar el orden de las entradas) aunque no estoy 100% seguro de eso ... así que aquí hay una reescritura más simple ( 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

y algunas muestras para probarlo:

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


Respuesta corta: setstructfields (si tiene la caja de herramientas de procesamiento de señales).

La solución oficial es publicada por Loren Shure en su blog MathWorks , y demostrada por SCFrench aquí y en la respuesta de Eitan T a una pregunta diferente . Sin embargo, si tiene Signal Processing Toolbox, una simple función no documentada ya lo hace: 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.

Internamente, utiliza fieldnames y un bucle for , por lo que es una función de conveniencia con comprobación de errores y recursividad para campos que a su vez son estructuras.

Ejemplo

La estructura "original":

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

Una segunda estructura que contiene un nuevo valor para ''count'' , y un nuevo campo, ''shape'' :

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

Llamar a setstructfields :

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

El campo ''count'' se actualiza . El campo ''shape'' se agrega . El campo ''color'' permanece sin cambios .

NOTA : Como la función no está documentada, puede cambiar o eliminarse en cualquier momento.


Sin colisiones, puedes hacer

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

Y esto es razonablemente eficiente. Sin embargo, los errores struct en nombres de campo duplicados, y la comprobación previa de ellos utilizando el rendimiento unique mata al punto de que un bucle es mejor. Pero aquí está lo que se vería:

M = [fieldnames(A)'' fieldnames(B)''; struct2cell(A)'' struct2cell(B)'']; [tmp, rows] = unique(M(1,:), ''last''); M=M(:, rows); C=struct(M{:});

Es posible que pueda hacer una solución híbrida al asumir que no hay conflictos y usar un try / catch alrededor de la llamada a struct para degradar con gracia al caso de manejo de conflictos.