webentwicklung-frage-antwort-db.com.de

Iteration durch Strukturfeldnamen in MATLAB

Meine Frage lässt sich leicht wie folgt zusammenfassen: "Warum funktioniert Folgendes nicht?"

teststruct = struct('a',3,'b',5,'c',9)

fields = fieldnames(teststruct)

for i=1:numel(fields)
  fields(i)
  teststruct.(fields(i))
end

Ausgabe:

ans = 'a'

??? Argument to dynamic structure reference must evaluate to a valid field name.

Zumal teststruct.('a')tut funktioniert. Und fields(i) druckt ans = 'a' aus.

Ich kann es nicht verstehen. 

65
noio

Sie müssen geschweifte Klammern ({}) verwenden, um auf fields zuzugreifen, da die fieldnames - Funktion ein cell array von Strings zurückgibt:

for i = 1:numel(fields)
  teststruct.(fields{i})
end

Wenn Sie auf Daten in Ihrem Zellen-Array zugreifen, verwenden Sie Klammern gibt nur ein anderes Zellen-Array zurück, das anders angezeigt wird als ein Zeichen-Array:

>> fields(1)  % Get the first cell of the cell array

ans = 

    'a'       % This is how the 1-element cell array is displayed

>> fields{1}  % Get the contents of the first cell of the cell array

ans =

a             % This is how the single character is displayed
87
gnovice

Da fields oder fns Zellenarrays sind, müssen Sie mit geschweiften Klammern {} indizieren, um auf den Inhalt der Zelle, d. H. Die Zeichenfolge, zugreifen zu können. 

Beachten Sie, dass Sie anstatt über eine Zahl eine Schleife ausführen können, auch fields direkt durchlaufen können, indem Sie die praktischen Matlab-Funktionen verwenden, mit denen Sie durch jedes Array gehen können. Die Iterationsvariable nimmt den Wert jeder Spalte des Arrays an.

teststruct = struct('a',3,'b',5,'c',9)

fields = fieldnames(teststruct)

for fn=fields'
  fn
  %# since fn is a 1-by-1 cell array, you still need to index into it, unfortunately
  teststruct.(fn{1})
end
15
Jonas

Ihr FNS ist ein Cellstr Array. Sie müssen mit {} anstelle von () indizieren, um den einzelnen String als char herauszuholen.

fns{i}
teststruct.(fns{i})

Die Indizierung mit () gibt ein 1-langes cellstr-Array zurück, das nicht dasselbe Format hat wie das char-Array, das die dynamische Feldreferenz ". (Name)" benötigt. Die Formatierung, insbesondere in der Displayausgabe, kann verwirrend sein. Versuchen Sie dies, um den Unterschied zu erkennen.

name_as_char = 'a'
name_as_cellstr = {'a'}
5
Andrew Janke

Sie können die für jede Toolbox unter http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each verwenden. 

>> signal
signal = 
sin: {{1x1x25 cell}  {1x1x25 cell}}
cos: {{1x1x25 cell}  {1x1x25 cell}}

>> each(fieldnames(signal))
ans = 
CellIterator with properties:

NumberOfIterations: 2.0000e+000

Verwendungszweck:

for bridge = each(fieldnames(signal))
   signal.(bridge) = Rand(10);
end

Es gefällt mir sehr gut Ein Dank geht natürlich an Jeremy Hughes, der die Toolbox entwickelte.

0
Jan