2017-10-18 68 views
2

我有包含數值的字段W,P,E的各種結構體。我想開發一個乾淨的方式加減這些結構而不必每次(這一直是我的解決方案迄今)如何在具有相同字段的情況下逐個添加,減去兩個結構體

例如拆包和子功能重新包裝,因爲:

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

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

我想成爲能夠做到X = S + M,並結了:

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

我現在試圖做到這一點,是一個新的類,它看起來的方式如下:

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 

這允許執行S + M並以與輸入相同的形式返回一個新變量。我通常對課程不熟悉,並且想知道這是否是適當的形式。如果是這樣,我可以繼續在methods部分添加minustimes的功能。但是,這似乎需要大量的重複代碼,我覺得必須有一個更簡單的解決方案。任何意見非常感謝。

+0

你可以通過'struct2array'將結構轉換爲數組,執行計算,並根據結構的每個字段的維數將結果賦給struct –

+0

這是一個很好的計劃,但我擔心沒有辦法檢查所有結構都具有相同的順序(即,因爲它們都是在代碼中的不同位置定義的,所以我不想擔心它們都按W,P,E的順序定義)如果這樣做有道理 – teepee

回答

4

以下代碼直接在結構上工作,而不將它們嵌套在類中。假定兩個輸入結構具有相同的字段名稱(在本例中爲W,P和E),但是它們的順序可能是任意的(您在評論中提到這對於您的應用程序很重要)。

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

所以定義

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

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

(注意M的相反的順序),並調用

X = structplus(S, M) 

產生與被下令像第一個參數字段名的結構:

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

謝謝,這就是我知道如果我使用cellfun而不是循環,我不能得到結構輸出 – teepee

+2

@teepee因此,'cell2struct(cellfun(@( n)M.(n)+ S。(n),fn,'UniformOutput',false),fn,1)'?但'cellfun'或多或少與'for'循環相同 –

+1

'cellfun' is *比明顯的循環更慢*每個非平凡的案例 – excaza

2

要展開Le Phlaux的答案是,您可以爲所需的二元運算符(例如@plus@minus)和子結構的工作遞歸

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 

爲了您的例子中,你會打電話X = structBinaryFunc(S, M, @plus);

相關問題