Iterate through a structure in MATLAB without 'fieldnames'
Asked Answered
G

2

7

The usual way to iterate through a struct data type in MATLAB is using the fieldnames() function as done in:

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

fields = fieldnames(mystruct);

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

Unfortunately, this always generates cell data types, and I would like to use this kind of iteration for a Matlab Function Block in SIMULINK that does not allow cell data types for code generation reasons.

Is there a way to iterate through a structure without making use of cell data types at the same time?

In Octave there is a neat way of that explained in https://www.gnu.org/software/octave/doc/interpreter/Looping-Over-Structure-Elements.html

for [val, key] = mystruct
  # do something esp. with 'key'
end

Does anybody know a similar way in MATLAB?

Gahnite answered 18/6, 2014 at 12:2 Comment(3)
I don't think that neat Octave feature has an equivalent in Matlab. If all you need to do is run a single function on all values, then structfun can help.Obaza
More precisely, I need to assign a vector to the value part of mystruct, that is, replace the values 3, 5, 9 with [10, 11, 12], to stay with the example. I don't know yet how to do this with a structfun statement under this circumstances. Any hints? Could it be a first step to transform the struct? Does a simple function (without {} occuring!) exists for transformation of a 1x1 struct to that 1x3 form: struct('key',{'a','b','c'},'val',{3,5,9})?Gahnite
As of MATLAB R2015b, this code should work. Support for fieldnames was added along with some other cell array support for code generation.Clareta
S
3

When generating code using MATLAB Coder or Simulink Coder, not only are cell arrays disallowed, but also referencing fields of a structure using dynamic names.

Since you can't use dynamic names, you should probably just repeat the content of your loop body multiple times, once for each field name, which (since you're not using dynamic names) you would know in advance.

Although this might be cumbersome from a programming point of view, I would guess it's likely to be slightly faster anyway when you generate code from it, as the code generation process should probably unroll the loop anyway.

Swordplay answered 18/6, 2014 at 12:32 Comment(0)
C
3

Edit: As of MATLAB R2015b, MATLAB Coder supports generating code for cell arrays and the fieldnames function. So the code snippet OP showed fully supports code generation.

Pre R2015b Answer

The MATLAB function structfun is supported for code generation with MATLAB Coder. If you set the 'UniformOutput' option to false, then the output of structfun is a struct that has the same fields as the input. The value of each field is the result of applying the supplied function handle to the corresponding field in the input struct.

mystruct = struct('a',3,'b',5,'c',9);
outstruct = structfun(@sin, mystruct, 'UniformOutput', false);

outstruct = 

    a: 0.1411
    b: -0.9589
    c: 0.4121

So you could write a subfunction which contains the body of the loop in your example and pass a handle to that subfunction to the call to structfun.

Clareta answered 18/6, 2014 at 12:32 Comment(1)
Note that although structfun is supported for code generation, and function handles are supported, anonymous functions are not, which is going to severely limit how applicable this solution is.Swordplay

© 2022 - 2024 — McMap. All rights reserved.