arrays - una - matriz vacia matlab
ActualizaciĆ³n de un campo en cada elemento de una matriz de estructura Matlab (3)
¿Todos los campos en esa estructura son escalares, o tienen el mismo tamaño? Si es así, la forma idiomática de Matlab para hacer esto es reorganizar su estructura para que sea una estructura escalar con matrices en cada uno de sus campos, en lugar de una matriz de estructuras con valores escalares en los campos. Luego puede realizar operaciones vectorizadas en los campos, como arr.val = arr.val + 3;
. Vea si puede reorganizar sus datos. Hacerlo de esta manera es mucho más eficiente tanto en tiempo como en memoria; Probablemente esa sea la razón por la que Matlab no proporciona una sintaxis conveniente para operar en campos de matrices de estructuras.
Supongamos que tengo una estructura array, donde cada elemento tiene un montón de campos, incluido uno llamado val
. Me gustaría incrementar el campo val
cada elemento en una cantidad constante, así:
for i = 1:length(arr)
arr(i).val = arr(i).val + 3;
end
Obviamente, esto funciona, pero creo que debería haber una manera de hacerlo en una sola línea de código (y no en bucle). Lo mejor que he encontrado son dos líneas y requiere una variable temporal:
newVals = num2cell([arr.val] + 3);
[arr.val] = deal(newVals{:});
¿Algunas ideas? Gracias.
Si la matriz de estructura que está intentando establecer es un conjunto de objetos gráficos (controladores de línea, controles de figura, controles de ejes, etc.), entonces necesita usar el set
funciones:
x = (1:10)'';
Y = rand(10,5);
l = plot(x,Y,''-k''); % returns an array of line handles in l
set(l,''Color'',''r''); % sets the property ''Color'' for all the five lines in l
Solo una nota, el deal
no es necesario allí:
[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})
La única otra forma en que sé cómo hacer esto (sin el bucle de foor) es usar arrayfun
para iterar sobre cada estructura en la matriz:
% make a struct array
arr = [ struct(''val'',0,''id'',1), struct(''val'',0,''id'',2), struct(''val'',0,''id'',3) ]
% some attempts
[arr.val]=arr.val; % fine
[arr.val]=arr.val+3; % NOT fine :(
% works !
arr2 = arrayfun(@(s) setfield(s,''val'',s.val+3),arr)
Ese último comando recorre cada estructura en arr
y devuelve una nueva donde s.val
se ha establecido en s.val=3
.
Creo que esto es en realidad menos eficiente que el anterior de dos líneas y el bucle for, porque devuelve una copia de arr
en lugar de operar en el lugar.
(Es una pena que Matlab no admita la indexación en capas como [arr.val]=num2cell([arr.val]+3){:}
).