Itération à travers les noms de champs struct dans MATLAB

Ma question se résume facilement à: “Pourquoi les actions suivantes ne fonctionnent-elles pas?”

teststruct = struct('a',3,'b',5,'c',9) fields = fieldnames(teststruct) for i=1:numel(fields) fields(i) teststruct.(fields(i)) end 

sortie:

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

Surtout que le teststruct.('a') fonctionne. Et les fields(i) affichent ans = 'a' .

Je ne peux pas la comprendre.

Vous devez utiliser des accolades ( {} ) pour accéder aux fields , car la fonction fieldnames renvoie un tableau de cellules contenant des chaînes:

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

L’utilisation de parenthèses pour accéder aux données de votre tableau de cellules renverra simplement un autre tableau de cellules, qui est affiché différemment d’un tableau de caractères:

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

Comme les fields ou les fns fields sont des tableaux de cellules, vous devez les indexer avec des accolades {} afin d’accéder au contenu de la cellule, c’est-à-dire à la chaîne.

Notez qu’au lieu de faire une boucle sur un nombre, vous pouvez également effectuer une boucle sur les fields directement, en utilisant des fonctionnalités Matlab soignées qui vous permettent de parcourir n’importe quel tableau. La variable d’itération prend la valeur de chaque colonne du tableau.

 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 

Votre fns est un tableau cellstr. Vous devez l’indexer avec {} au lieu de () pour obtenir la chaîne unique en tant que char.

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

L’indexation avec () renvoie un tableau cellstr de 1 longueur, qui n’est pas le même format que le tableau de caractères recherché par la référence de champ dynamic “. (Nom)”. Le formatage, en particulier dans l’affichage, peut être source de confusion. Pour voir la différence, essayez ceci.

 name_as_char = 'a' name_as_cellstr = {'a'} 

Vous pouvez utiliser le pour chaque boîte à outils à partir de http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each .

 >> signal signal = sin: {{1x1x25 cell} {1x1x25 cell}} cos: {{1x1x25 cell} {1x1x25 cell}} >> each(fieldnames(signal)) ans = CellIterator with properties: NumberOfIterations: 2.0000e+000 

Usage:

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

J’aime beaucoup. Le crédit va bien sûr à Jeremy Hughes qui a développé la boîte à outils.