unndreay
unndreay

Reputation: 383

Iterate through a structure in MATLAB without 'fieldnames'

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?

Upvotes: 7

Views: 3494

Answers (2)

Ryan Livingston
Ryan Livingston

Reputation: 1928

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.

Upvotes: 3

Sam Roberts
Sam Roberts

Reputation: 24127

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.

Upvotes: 3

Related Questions