HeinrichStack
HeinrichStack

Reputation: 694

MATLAB -> struct.field(1:end).field?

Is there a way that I get all the structure subsubfield values of a subfield in one line ? Something like this :

struct.field(1:end).field 

Upvotes: 1

Views: 1647

Answers (2)

MattLab
MattLab

Reputation: 303

Simple Structure Example

aStruct.subField = struct('subSubField', {1;2;3;4})

So that

aStruct.subField(1).subSubField == 1
aStruct.subField(1).subSubField == 2

Etc. Then the values of the leaf nodes can be obtained via a one-liner as

valueLeafs = [aStruct.subField.subSubField];

Which can be checked via assert(all(valueLeafs == [1,2,3,4])).

Non-Scalar Structure Example

The above one-liner also works when the leaf node values are non-scalar such that they can be horizontally concatenated. For example

bStruct.subField = struct('subSubField', {[1,2];[3,4]})
valueLeafs_b     = [bStruct.subField.subSubField]; % works okay
cStruct.subField = struct('subSubField', {[1,2];[3;4]})
valueLeafs_c     = [cStruct.subField.subSubField]; % error: bad arg dims

Distinct Class Structure Example

The one-line solution given previously does not work whenever the leaf node values are different class since they cannot - in general, be concatenated. However, use of arrayfun and a tricky anonymous function typically provide the required indexing technique:

dStruct.subField = struct('subSubField', {[1;2];'myString'});
valueLeafs_d     = arrayfun(@(x) x.subSubField, dStruct.subField, 'UniformOutput', false)

Upvotes: 1

Max
Max

Reputation: 2131

If I understand your question aright, you want to collect all the fields of the second-level structure, with the name 'field', into a single output array. It doesn't quite meet your request for a one-liner, but you can do it like this:

a.field1.a = 1;
a.field1.b = 2;
a.field2.a = 3;
a.field2.b = 4;

result = [];
for x = fieldnames(a)'
     result = horzcat(result, a.(x{:}).a);
end

The ending value of result is [1 3]

Upvotes: 1

Related Questions