matlab - una - ¿Cómo accedo a los campos de la estructura de forma dinámica?
struct matlab examples (6)
El enfoque de getfield está bien (aunque no tengo disponible MATLAB ahora mismo y no me queda claro por qué lo anterior no funcionaría).
Para una estructura de datos alternativa, es posible que también desee examinar las matrices de MATLAB. También le permiten almacenar e indexar vectores de longitud variable.
Tengo una estructura con muchos campos que son vectores de diferentes longitudes. Me gustaría acceder a los campos dentro de un ciclo, en orden. Intenté getfield de la siguiente manera, pero a MATLAB no le gusta eso. ¿Cómo puedo hacer esto?
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
Estoy usando estructuras en primer lugar porque una matriz tendría problemas con las diferentes longitudes de campo. ¿Hay una mejor alternativa a eso?
Hay tres puntos que me gustaría hacer aquí:
La razón por la que recibe un error en el código anterior es debido a la forma en que indexa
SNames
. La funciónfieldnames
devuelve una matriz de cadenas de celdas , por lo que debe usar la indexación de contenido (es decir, llaves) para acceder a los valores de cadena. Si cambia la cuarta línea de su código a esto:field = getfield(S, SNames{loopIndex});
entonces tu código debería funcionar sin error.
Según lo sugerido por MatlabDoug , puede usar nombres de campo dinámicos para evitar tener que usar
getfield
(lo que produce un código de aspecto más limpio, en mi opinión).La sugerencia de Adam de usar una matriz de celdas en lugar de una estructura está justo en la marca. En general, esta es la mejor manera de recopilar una serie de matrices de diferente longitud en una sola variable. Tu código terminaría luciendo algo como esto:
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
Pruebe la referencia de campo dinámico donde coloca una cadena entre paréntesis como se ve en la línea que define las cosas .
S = struct(''A'', [1 2], ''B'',[3 4 5]);
SNames = fieldnames(S);
for loopIndex = 1:numel(SNames)
stuff = S.(SNames{loopIndex})
end
Estoy de acuerdo con Steve y Adam. Usa celdas ¡Esta sintaxis es adecuada para personas en otras situaciones!
Puede usar notación de dos puntos para evitar índices:
S = struct(''A'', [1 2], ''B'',[3 4 5]);
SNames = fieldnames(S);
for SName = [SNames{:}]
stuff = S.(SName)
end
Si necesita usar una estructura, lo que encontré que funcionó muy bien fue primero convertirla a una celda, entonces tiene lo mejor de ambos mundos.
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
Usé algo similar para algo que se generó en una estructura y luego tuve que acceder a él como una matriz, en ese caso era tan simple como
M = cell2mat(struct2cell(S));
Para convertirlo en una matriz
Solo para agregar otra respuesta a la mezcla. Me gusta la solución de @Niver pero solo funciona para campos con nombres de una sola letra. La solución que utilicé fue:
S = struct(''A'', [1 2], ''B'',[3 4 5], ''Cee'', [6 7]);
for SName = fieldnames(S)''
stuff = S.(SName{1})
end
for
iterará a través de las columnas de una matriz de celdas (de ahí la transposición en fieldnames(S)''
. Para cada bucle, SName se convierte en una matriz de celdas de 1x1, por lo que usamos indexación de contenido para acceder al primer y único elemento con SName{1}
.