web-dev-qa-db-fra.com

Itération dans les noms de champs de structure dans MATLAB

Ma question se résume facilement comme suit: "Pourquoi les éléments suivants ne fonctionnent-ils 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 teststruct.('a')fait fonctionne. Et fields(i) affiche ans = 'a'.

Je n'arrive pas à comprendre. 

65
noio

Vous devez utiliser des accolades ({}) pour accéder à fields, car la fonction fieldnames renvoie un tableau cell de 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
87
gnovice

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

Notez qu'au lieu de boucler sur un nombre, vous pouvez également boucler directement sur fields, en utilisant des fonctionnalités ordonnées de Matlab qui vous permettent de parcourir en boucle 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
15
Jonas

Votre fns est un tableau cellstr. Vous devez y indexer avec {} au lieu de () pour obtenir la chaîne unique sous forme de caractère.

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

Son indexation avec () renvoie un tableau cellstr long de 1, dont le format n'est pas le même que celui du tableau de caractères souhaité par la référence de champ dynamique ". (Nom)". Le formatage, en particulier dans l'affichage, peut être déroutant. Pour voir la différence, essayez ceci.

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

Vous pouvez utiliser la 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. Nous remercions bien sûr Jeremy Hughes qui a développé la boîte à outils.

0
Jan