2017-10-18 5 views
2

J'ai différentes structures avec des champs W, P, E, qui contiennent des valeurs numériques. Je veux développer une manière propre à ajouter et soustraire ces struct sans déballer et remballer en sous-fonctions chaque fois (ce qui a été ma solution jusqu'ici)Comment ajouter, soustraire, etc. deux structures élément par élément quand elles ont les mêmes champs

Par exemple, étant donné:

S.W = 2 
S.P = 3 
S.E = 4 

M.W = 20 
M.P = 30 
M.E = 40 

Je veux être capable de faire X = S + M et finissent avec:

X.W = 22 
X.P = 33 
X.E = 44 

Ma tentative actuelle de ce faire, est au moyen d'une nouvelle classe, qui se présente comme suit:

classdef CV 
    properties 
     W 
     P 
     E 
    end 
    methods 
     function r = plus(o1,o2) 
      r = CV; 
      r.E = o1.E + o2.E; 
      r.P = o1.P + o2.P; 
      r.W = o1.W + o2.W; 
     end 
    end 
end 

Cela permet de faire S + M et renvoie une nouvelle variable sous la même forme que les entrées. Je ne suis généralement pas familier avec les cours, et je voulais savoir si c'était une bonne forme. Si oui, je pourrais aller de l'avant et ajouter des fonctions pour minus et times dans la section methods. Cependant, cela semble exiger beaucoup de code répétitif et je pense qu'il doit y avoir une solution plus simple. Tout conseil est fort apprécié.

+0

Vous pouvez convertir struct en tableau par 'struct2array', faire le calcul et affecter le résultat dans la structure en fonction de la dimension de chaque champ de la structure –

+0

C'est un bon plan mais je crains de ne pas avoir un moyen de vérifier que toutes les structures ont le même ordre (ie qu'elles sont toutes définies à des endroits différents dans le code, je ne veux pas m'inquiéter qu'elles aient toutes été définies dans l'ordre W, P, E Si cela a du sens – teepee

Répondre

4

Le code suivant fonctionne directement sur les structures sans les imbriquer dans une classe. Il est supposé que les deux structures d'entrée ont les mêmes noms de champs (dans cet exemple W, P et E), cependant, l'ordre de ceux-ci peut être arbitraire (vous avez mentionné dans un commentaire que ceci est important pour votre application).

function X = structplus(S, M) 
fn = fieldnames(S); 
for i = 1 : numel(fn) 
    X.(fn{i}) = M.(fn{i}) + S.(fn{i}); 
end 
end 

définissant ainsi

S.W = 2 
S.P = 3 
S.E = 4 

M.E = 40 
M.P = 30 
M.W = 20 

(notez l'ordre inverse de M) et appelant

X = structplus(S, M) 

donne un struct avec les noms de champs qui sont classés comme le premier argument:

X = 
    struct with fields: 
    W: 22 
    P: 33 
    E: 44 
+0

Merci, c'est Si vous utilisez une cellule plutôt que la boucle, je ne peux pas obtenir une sortie struct – teepee

+2

@teepee Donc, 'cell2struct (cellfun (@ (n) M. (n) + S. (n), fn, 'UniformOutput', faux), fn, 1) '? Mais' cellfun' est plus ou moins la même chose qu'une boucle 'for' –

+1

' cellfun' est * plus lent que la boucle explicite dans jolie muc h tous les cas non triviaux – excaza

2

Pour développer La réponse de Le Phlaux, vous pouvez fournir un handle de fonction à l'opérateur binaire requis (par ex. @plus, @minus) et le travail sur les sous-structures récursive

function out = structBinaryFunc(in1, in2, func) 
fn = fieldnames(in1); 
for ii = 1:numel(fn) 
    if isstruct(in1.(fn{ii})) 
     out.(fn{ii}) = structBinaryFunc(in1.(fn{ii}), in2.(fn{ii}), func) 
    else 
     out.(fn{ii}) = func(in1.(fn{ii}), in2.(fn{ii})); 
    end 
end 

Pour votre exemple, vous appelez X = structBinaryFunc(S, M, @plus);.