2009-12-10 39 views
32

我有一個很多領域的結構是不同長度的向量。我想按順序訪問循環內的字段。我嘗試了getfield,但是MATLAB不喜歡這樣。我怎樣才能做到這一點?如何動態訪問結構域?

S = struct('A', [1 2], 'B',[3 4 5]); 
SNames = fieldnames(S); 
for loopIndex = 1:2 
    field = getfield(S, SNames(loopIndex)); 
    %do stuff w/ field 
end 
??? Index exceeds matrix dimensions 

我在第一個地方使用結構,因爲數組會有不同的字段長度有問題。有更好的選擇嗎?

回答

42

嘗試使用動態字段引用,將字符串放在括號中,如定義東西的行所示。

S = struct('A', [1 2], 'B',[3 4 5]); 
SNames = fieldnames(S); 
for loopIndex = 1:numel(SNames) 
    stuff = S.(SNames{loopIndex}) 
end 

我同意Steve和Adam。使用單元格。這種語法適用於其他情況下的人!

5

getfield方法沒問題(雖然我現在沒有MATLAB可用,但我不清楚爲什麼上述方法無效)。

對於另一種數據結構,您可能還需要查看MATLAB單元陣列。他們還可以讓你存儲和索引不同長度的矢量。

+1

鑑於你爲什麼您使用的是結構的描述,我與亞當同意,你應該考慮使用一個單元陣列來代替。 –

16

有三點,我想在這裏提出:

  • 你在你上面的代碼中得到一個錯誤的原因是因爲你是如何索引SNames的。函數fieldnames返回字符串的cell array,因此您必須使用content indexing(即大括號)來訪問字符串值。如果您將代碼中的第四行更改爲:

    field = getfield(S, SNames{loopIndex}); 
    

    那麼您的代碼應該沒有錯誤地工作。

  • 正如MatlabDoug所建議的那樣,您可以使用dynamic field names來避免必須使用getfield(在我看來,這會產生更清晰的代碼)。

  • suggestion from Adam使用cell array而不是結構是正確的標誌。這通常是將一系列不同長度的數組收集到一個變量中的最佳方法。你的代碼最終會看起來像這樣:

    S = {[1 2], [3 4 5]};  % Create the cell array 
    for loopIndex = 1:numel(S) % Loop over the number of cells 
        array = S{loopIndex};  % Access the contents of each cell 
        % Do stuff with array 
    end 
    
+0

使用單元陣列,而不是一個結構更簡潔,但。 – Wok

3

您可以使用冒號表示法來避免指標:

S = struct('A', [1 2], 'B',[3 4 5]); 
SNames = fieldnames(S); 
for SName = [SNames{:}] 
    stuff = S.(SName) 
end 
2

如果你需要使用一個結構,我發現非常行之有效爲先轉換成一個單元格,然後你就擁有了兩全其美的世界。

S = struct('A', [1 2], 'B',[3 4 5]); 
S_Cell = struct2cell(S); 
%Then as per gnovice 
for loopIndex = 1:numel(S_Sell) % Loop over the number of cells 
    array = S{loopIndex};   % Access the contents of each cell 
    %# Do stuff with array 
end 

我曾經因爲這是在結構中產生的,然後我需要訪問它像一個矩陣一些類似的事情,在這種情況下,它是那樣簡單

M = cell2mat(struct2cell(S)); 

要將其轉換爲矩陣

+0

M = table2array (struct2table(S)); – BigChief

0

只是爲混合添加另一個答案。我喜歡@Niver的解決方案,但它只適用於單字母名稱的字段。我所用的溶液是:

S = struct('A', [1 2], 'B',[3 4 5], 'Cee', [6 7]); 
for SName = fieldnames(S)' 
    stuff = S.(SName{1}) 
end 

for將通過單元陣列(因此上fieldnames(S)'轉置的列迭代對於每個循環,所以我們使用內容索引來訪問所述第一和僅SNAME變爲1x1的單元陣列。元素與SName{1}