2010-05-10 13 views
58

Mi pregunta se resume fácilmente como: "¿Por qué no funciona lo siguiente?"Iterar a través de nombres de campos struct en MATLAB

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

fields = fieldnames(teststruct) 

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

de salida:

ans = 'a' 

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

Especialmente desde hace teststruct.('a') trabajo. Y fields(i) imprime ans = 'a'.

No puedo entenderlo.

Respuesta

75

usted tiene que utilizar llaves ({}) para acceder a fields, ya que la función fieldnames devuelve un cell array de cadenas:

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

uso de paréntesis para access data in your cell array se acaba de volver otra serie de células, que se muestra de forma diferente a partir una matriz de caracteres:

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

Tu respuesta es increíblemente útil y ha aclarado algunas cosas que me han estado molestando literalmente durante años. –

5

Su fns es una matriz de celdas. Necesitas indexarlo con {} en lugar de() para obtener la única cadena como char.

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

Indexing en a ella con() devuelve una matriz cellstr 1-largo, que no es el mismo formato que la matriz de caracteres que el "(nombre)" referencia de campo dinámico quiere. El formateo, especialmente en la salida de la pantalla, puede ser confuso. Para ver la diferencia, intente esto.

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

Desde fields o fns son paneles de células, que tienen al índice con llaves {} con el fin de acceder a los contenidos de la célula, es decir, la cadena.

Tenga en cuenta que en lugar de recorrer un número, también puede recorrer el fields directamente, haciendo uso de unas características de Matlab que le permiten recorrer cualquier matriz. La variable de iteración toma el valor de cada columna de la matriz.

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 
0

Usted puede utilizar la caja de herramientas para cada uno 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 

Uso:

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

me gusta mucho. Crédito, por supuesto, ir a Jeremy Hughes que desarrolló la caja de herramientas.

Cuestiones relacionadas