1

I have a 1x1 Matlab struct with 15 fields

results = 

     RAR_no_compartments_2_0: [1x1 struct]
     RAR_no_compartments_2_1: [1x1 struct]
    RAR_no_compartments_2_10: [1x1 struct]
    RAR_no_compartments_2_11: [1x1 struct]
    RAR_no_compartments_2_12: [1x1 struct]
    RAR_no_compartments_2_13: [1x1 struct]
    RAR_no_compartments_2_14: [1x1 struct]
     RAR_no_compartments_2_2: [1x1 struct]
     RAR_no_compartments_2_3: [1x1 struct]
     RAR_no_compartments_2_4: [1x1 struct]
     RAR_no_compartments_2_5: [1x1 struct]
     RAR_no_compartments_2_6: [1x1 struct]
     RAR_no_compartments_2_7: [1x1 struct]
     RAR_no_compartments_2_8: [1x1 struct]
     RAR_no_compartments_2_9: [1x1 struct]

I'm trying to cycle through each of these in a for loop:

model_names=fieldnames(results); %get the names of each sub-struct
fieldname_dims=size(fieldnames(results)); %get dimensions of each struct
for i=1:fieldname_dims(1), %iterate over number of substructs
    name=model_names(i) %get the model name
    results.(name) %access the substruct
end

However Matlab returns the following error:

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

Could somebody please explain to me why this is an invalid field name?

Suever
  • 64,497
  • 14
  • 82
  • 101
CiaranWelsh
  • 7,014
  • 10
  • 53
  • 106
  • 2
    the return of `fieldnames` is a cell array. You need to index it with `{}`, not `()` – sco1 Jan 15 '16 at 13:35

2 Answers2

3

This is precisely what structfun is made for. It allows you to loop through all the fields of a structure.

a = struct('a', 1, 'b', 2, 'c', 3);
structfun(@(x)disp(x), a)

1
2
3

Alternately, you may consider storing an array of structures rather than a structure where the fields have numbers in them like you have. Any time that you are reliant on a fieldname to know ordering, it may be better to use a different data structure.

For in your data, rather than having a fieldname of RAR_no_compartments_2_0 you'd simply assign the struct assigned to that field by index

RAR_no_compartments(1) = results.RAR_no_compartments_2_0;
RAR_no_compartments(2) = results.RAR_no_compartments_2_1;
...

This way, rather than a 1 x 1 struct with 15 fields, you'd have a 1 x 15 array of structs which is much easier to deal with natively within MATLAB.

Just a thought.

Suever
  • 64,497
  • 14
  • 82
  • 101
2

The problem is that fieldnames returns a cell array, so you have to use curly brackets to access the content of a cell. This should work:

model_names=fieldnames(results);
fieldname_dims=size(fieldnames(results),1);
for i=1:fieldname_dims
    name=model_names{i};
    results.(name)
end

The whole thing can be simplified by actually iterating over the cell array instead of using a counter and temporary variables:

for name = fieldnames(results).'
    results.(name{:})  % do whatever with your field
end

However, the correct way to access all fields of a struct is structfun—see Suever's answer.

Community
  • 1
  • 1
dasdingonesin
  • 1,347
  • 1
  • 10
  • 16