How to loop over a structure in matlab

467 views (last 30 days)
Hi, I am new to matlab and learning it. I have a 1(1X1) main struct which again has 5(1X1) nested structs inside it which has 3(1X100) tables and I would like to finally fetch the value of those 3 tables but not sure how. Please help
  3 Comments
MattC
MattC on 27 Feb 2023
% I have this for loop I used to get to the table and it works as expected
% however if you see I am using Struct1{1} and Struct2{1} so this is only
% giving me the value of 1st elements I would like to reuse this same code
% and get values of all the elements not the 1st one. Is that possible?
for Struct1 = fieldnames(Data.Struct1)
for Struct2 = fieldnames(Data.Struct1.(Struct1{1})) %Gets the value for Struct2
for Table1 = fieldnames(Data.Struct1.(Struct1{1}).(Struct2{1})) %Gets the value for Table1
Struct2_Table1 = (Data.Struct1.(Struct1{1}).(Struct2{1}));
end
end
end
Stephen23
Stephen23 on 27 Feb 2023
Edited: Stephen23 on 28 Feb 2023
@Learn Matlab: Please upload some representative data in a MAT file by clicking the paperclip button. It does not have to be your top-secret data, just something with exactly the same arrangement. Data descriptions are rarely correct.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 27 Feb 2023
Edited: Stephen23 on 27 Feb 2023
As far as I can tell, this is your data structure (for simplicity I will define only two field Names, but the code works for any number of Names). I will assume that you really do mean table-type when you write the term "table":
S.Name1.Table1 = array2table(rand(7,5));
S.Name1.Table2 = array2table(rand(7,5));
S.Name1.Table3 = array2table(rand(7,5));
S.Name2.Table1 = array2table(rand(7,5));
S.Name2.Table2 = array2table(rand(7,5));
S.Name2.Table3 = array2table(rand(7,5));
I will assume that your goal is to vertically concatenate the tables together (even though I asked for clarification here, so far you have not specified this), and that you want them concatenated in the same order as the fields have. I will also assume that the tables have compatible sizes, types, column/variable names, etc.
C = struct2cell(S);
T = [C{:}]
T = 1×2 struct array with fields:
Table1 Table2 Table3
T1 = vertcat(T.Table1)
T1 = 14×5 table
Var1 Var2 Var3 Var4 Var5 ________ _______ ________ _______ ________ 0.99227 0.4364 0.95854 0.33011 0.30881 0.12542 0.255 0.2363 0.20619 0.78108 0.011572 0.90123 0.88262 0.8375 0.91407 0.70267 0.46694 0.059236 0.67056 0.16106 0.69667 0.72092 0.64737 0.65369 0.78121 0.75244 0.63781 0.67781 0.63327 0.34179 0.026504 0.32164 0.20523 0.34102 0.57129 0.30376 0.66852 0.22986 0.69838 0.061212 0.49366 0.99997 0.23237 0.55552 0.9058 0.23795 0.11266 0.85971 0.51135 0.88532 0.14828 0.15646 0.53883 0.32337 0.96484 0.56345 0.87312 0.16723 0.32941 0.2775 0.3072 0.41575 0.59287 0.53829 0.61671 0.20481 0.28157 0.12718 0.59056 0.82286
T2 = vertcat(T.Table2)
T2 = 14×5 table
Var1 Var2 Var3 Var4 Var5 ________ ________ _______ ________ ________ 0.54563 0.38388 0.29637 0.37261 0.90489 0.037324 0.59359 0.53215 0.73093 0.38226 0.21604 0.33477 0.7297 0.55717 0.14877 0.17777 0.3707 0.56774 0.76761 0.62979 0.97126 0.79812 0.27897 0.6427 0.14614 0.87722 0.99473 0.57715 0.24911 0.74901 0.98824 0.42447 0.23163 0.052579 0.085909 0.90763 0.76468 0.21964 0.034569 0.16539 0.86225 0.20711 0.83592 0.14267 0.72307 0.073437 0.33883 0.35699 0.87312 0.24588 0.52598 0.554 0.7246 0.2518 0.85848 0.12421 0.019399 0.39709 0.61751 0.082109 0.33215 0.67097 0.20596 0.71881 0.29208 0.31202 0.20779 0.3271 0.063916 0.53378
T3 = vertcat(T.Table3)
T3 = 14×5 table
Var1 Var2 Var3 Var4 Var5 ________ _________ _______ _________ _______ 0.36188 0.096081 0.55646 0.0028935 0.47708 0.97371 0.66854 0.29259 0.77311 0.1254 0.51468 0.0064368 0.17519 0.88172 0.48252 0.035424 0.25941 0.639 0.95591 0.31873 0.55395 0.69916 0.50231 0.2845 0.39384 0.40546 0.96839 0.8114 0.4037 0.97745 0.6857 0.69703 0.7666 0.55353 0.92403 0.49166 0.46666 0.95838 0.59512 0.5872 0.16437 0.35974 0.70321 0.023214 0.17211 0.02512 0.62842 0.18175 0.19001 0.16561 0.12052 0.94594 0.4946 0.61787 0.55298 0.96801 0.69281 0.98424 0.52184 0.93673 0.57205 0.10585 0.62255 0.15836 0.62718 0.63864 0.42176 0.75274 0.19087 0.88685
This code uses comma-separated lists:
  2 Comments
MattC
MattC on 27 Feb 2023
Thanks for the quick response @Stephen23. I believe this works. However, a quick follow up question: Is there a way we would get the values for each Names as well. What I mean by that is right now we the variable T which has the Tables and then the T1 variable which has the table1 value for both names 1,2 and hence the 14x5.
So, when I say if there is a way we could get values for each names lets say we would have TN1 table with only Name1's data then another table TN2 with Name2's data separate?
Stephen23
Stephen23 on 28 Feb 2023
Edited: Stephen23 on 28 Feb 2023
"a way we could get values for each names lets say we would have TN1 table with only Name1's data then another table TN2 with Name2's data separate?"
Of course, just replace VERTCAT with a cell constructor:
C1 = {T.Table1}
C2 = {T.Table2}
C3 = {T.Table3}
Then you can access the data using basic, efficient indexing:
For example the 2nd Name of Table1:
C1{2}
Your request is confusing because earlier you wrote that you want "... to store those 3 final tables separately and not planning on giving them unique variable names... not planning on giving them unique variable names", i.e. that you expected exactly three output tables. Now you are apparently asking for exactly that which you stated you were not asking for. Changing what you request makes it harder to help you.
Do NOT force yourself into writing slow, complex, inefficient, buggy code by using dynamically-named variables:

Sign in to comment.

More Answers (1)

Cameron
Cameron on 27 Feb 2023
Depends on how your data is placed in the function. Like @Walter Roberson said, structfun works well if your data looks like this
T.S.X = rand(1,1000);
T.S.Y = rand(1,1000)*2;
T.S.Z = rand(1,1000)*3;
p = structfun(@median,T.S);
disp(p)
Another way to do it is to loop through them.
T.S.X{1} = rand(1,1000);
T.S.X{2} = rand(1,1000)*2;
T.S.X{3} = rand(1,1000)*3;
for xx = 1:length(T.S.X)
disp(median(T.S.X{xx}))
end
  6 Comments
MattC
MattC on 27 Feb 2023
Edited: MattC on 27 Feb 2023
@Stephen23, sorry I am really not at the liberty to share the data. I tried to be as elaborate as possible with the description sorry for the confusion it may have caused. So, I would like to store those 3 final tables separately and not planning on giving them unique variable names. I would just like store them as tables
Walter Roberson
Walter Roberson on 28 Feb 2023
MainData --> Name1 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
Okay, that is 3 tables. Suppose you store those into variables named Table1, Table2 and Table3
MainData --> Name2 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
okay, that is 3 more tables. Do you want to now overwrite variables named Table1, Table2 and Table3 or do you want them stored into a different variable name?
If you were wanting to store to Table1{1} for Name1 and Table1{2} for Name2 and so on, using a cell array with one entry per field, then that is relatively easy. But if you want to store into (for example) Name1_Table1 and Name2_Table1 and so on, with the variable name depending on the field name, then the code gets uglier.

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!