Extract data from struct array (2024)

61 views (last 30 days)

Show older comments

Daniel Stein on 1 Jun 2023

  • Link

    Direct link to this question

    https://ms-intl.mathworks.com/matlabcentral/answers/1976894-extract-data-from-struct-array

  • Link

    Direct link to this question

    https://ms-intl.mathworks.com/matlabcentral/answers/1976894-extract-data-from-struct-array

Edited: Stephen23 on 1 Jun 2023

I have a struct array that each element contains substructures with data that I would like to extract into a numeric array or timeseries. The data structure is set up similar to the example I created below:

dt = 1/1000;

T = 5;

t = 0:dt:T;

data = struct([]);

for it = 1:length(t)

data(it).t = t(it);

data(it).sys = genStruct(t(it));

end

function sOut = genStruct(t)

sOut = struct;

sOut.sys1 = struct;

sOut.sys2 = struct;

sOut.sys1.sub1 = genSubsystemStruct(t);

sOut.sys1.sub2 = genSubsystemStruct(t);

sOut.sys2.sub1 = genSubsystemStruct(t);

sOut.sys2.sub2 = genSubsystemStruct(t);

end

function sOut = genSubsystemStruct(t)

sOut = struct;

sOut.t = t;

sOut.dataPoint1 = randn();

sOut.dataPoint2 = randn();

end

Since data(1:10).sys.sys1.sub1.dataPoint1 does not work, the only method I have found to get an array from this structure is to create a structure map and loop over struct as shown below:

sFieldsOfInterest = struct; % Data map

sFieldsOfInterest.data = ["t"]; % Fields listed under data are saved to a row

sFieldsOfInterest.sys = struct;

sFieldsOfInterest.sys.sys1 = struct('sub1', struct('data', ["dataPoint1", "dataPoint2"]), ...

'sub2', struct('data', ["dataPoint1", "dataPoint2"]));

sFieldsOfInterest.sys.sys2 = struct('sub1', struct('data', ["dataPoint1", "dataPoint2"]), ...

'sub2', struct('data', ["dataPoint1", "dataPoint2"]));

dataArray = [];

for ii = 1:length(data)

dataArray(end+1,:) = getDataFromStructArray(data(ii), sFieldsOfInterest);

end

function row = getDataFromStructArray(dataStruct, structure)

row = [];

f = fields(structure);

for ii = 1:length(f)

if f{ii} == "data"

fois = structure.(f{ii}); % Fields of interest

for foi = fois

row = [row dataStruct.(foi)];

end

else

row = [row getDataFromStructArray(dataStruct.(f{ii}), structure.(f{ii}))];

end

end

end

Is there a better way to access this data? For the most part, the data fields of interest are not multi-dimensional arrays.

0 Comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

Answers (1)

Stephen23 on 1 Jun 2023

  • Link

    Direct link to this answer

    https://ms-intl.mathworks.com/matlabcentral/answers/1976894-extract-data-from-struct-array#answer_1248524

  • Link

    Direct link to this answer

    https://ms-intl.mathworks.com/matlabcentral/answers/1976894-extract-data-from-struct-array#answer_1248524

Edited: Stephen23 on 1 Jun 2023

Open in MATLAB Online

"Since data(1:10).sys.sys1.sub1.dataPoint1 does not work.."

First lets generate your sample structure:

dt = 1/1000;

T = 5;

t = 0:dt:T;

data = struct([]);

for it = 1:length(t)

data(it).t = t(it);

data(it).sys = genStruct(t(it));

end

Because all of your nested structures are scalar you can simply use ARRAYFUN:

F = @(s)s.sys.sys1.sub1.dataPoint1;

V = arrayfun(F, data)

V = 1×5001

-1.1297 0.6164 -0.6211 0.3362 0.0718 -0.4912 -0.1255 1.1036 -0.2441 -1.3993 -0.2652 0.0855 1.3243 -1.7874 -0.4221 -1.1474 0.4290 0.0323 -0.1947 -0.4415 0.4525 0.4684 0.4993 -0.3849 -0.7085 0.5279 2.2160 -0.6229 1.3110 -0.6714

Or you could use a few comma-separated lists:

s1 = [data.sys];

s2 = [s1.sys1];

s3 = [s2.sub1];

V = [s3.dataPoint1]

V = 1×5001

-1.1297 0.6164 -0.6211 0.3362 0.0718 -0.4912 -0.1255 1.1036 -0.2441 -1.3993 -0.2652 0.0855 1.3243 -1.7874 -0.4221 -1.1474 0.4290 0.0323 -0.1947 -0.4415 0.4525 0.4684 0.4993 -0.3849 -0.7085 0.5279 2.2160 -0.6229 1.3110 -0.6714

https://www.mathworks.com/help/matlab/matlab_prog/comma-separated-lists.html

https://www.mathworks.com/matlabcentral/answers/1656435-tutorial-comma-separated-lists-and-how-to-use-them

"For the most part, the data fields of interest are not multi-dimensional arrays."

What sizes do you expect the output to be? How do you want them concatenated together?

If using comma-separated lists then you will need to carefully consider using e.g. VERTCAT, HORZCAT, a cell array, ...

You may also find dynamic fieldnames useful:

https://www.mathworks.com/help/matlab/matlab_prog/generate-field-names-from-variables.html

If you want complete flexibility (only gets one field value, but allows any number of nested sturctures, can define all levels and indexing via a cell array i.e. comma-separated list):

https://www.mathworks.com/help/matlab/ref/getfield.html

function sOut = genStruct(t)

sOut = struct;

sOut.sys1 = struct;

sOut.sys2 = struct;

sOut.sys1.sub1 = genSubsystemStruct(t);

sOut.sys1.sub2 = genSubsystemStruct(t);

sOut.sys2.sub1 = genSubsystemStruct(t);

sOut.sys2.sub2 = genSubsystemStruct(t);

end

function sOut = genSubsystemStruct(t)

sOut = struct;

sOut.t = t;

sOut.dataPoint1 = randn();

sOut.dataPoint2 = randn();

end

0 Comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

See Also

Categories

MATLABLanguage FundamentalsData TypesStructures

Find more on Structures in Help Center and File Exchange

Tags

  • struct
  • array

Products

  • MATLAB

Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

An Error Occurred

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.


Extract data from struct array (3)

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list

Americas

  • América Latina (Español)
  • Canada (English)
  • United States (English)

Europe

  • Belgium (English)
  • Denmark (English)
  • Deutschland (Deutsch)
  • España (Español)
  • Finland (English)
  • France (Français)
  • Ireland (English)
  • Italia (Italiano)
  • Luxembourg (English)
  • Netherlands (English)
  • Norway (English)
  • Österreich (Deutsch)
  • Portugal (English)
  • Sweden (English)
  • Switzerland
    • Deutsch
    • English
    • Français
  • United Kingdom(English)

Asia Pacific

  • Australia (English)
  • India (English)
  • New Zealand (English)
  • 中国
  • 日本Japanese (日本語)
  • 한국Korean (한국어)

Contact your local office

Extract data from struct array (2024)

References

Top Articles
Latest Posts
Article information

Author: Francesca Jacobs Ret

Last Updated:

Views: 5524

Rating: 4.8 / 5 (68 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Francesca Jacobs Ret

Birthday: 1996-12-09

Address: Apt. 141 1406 Mitch Summit, New Teganshire, UT 82655-0699

Phone: +2296092334654

Job: Technology Architect

Hobby: Snowboarding, Scouting, Foreign language learning, Dowsing, Baton twirling, Sculpting, Cabaret

Introduction: My name is Francesca Jacobs Ret, I am a innocent, super, beautiful, charming, lucky, gentle, clever person who loves writing and wants to share my knowledge and understanding with you.