How to loop over a structure in matlab

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 comentarios

Walter Roberson
Walter Roberson el 27 de Feb. de 2023
structfun()
% 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 el 27 de Feb. de 2023
Editada: Stephen23 el 28 de Feb. de 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.

Iniciar sesión para comentar.

 Respuesta aceptada

Stephen23
Stephen23 el 27 de Feb. de 2023
Editada: Stephen23 el 27 de Feb. de 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 comentarios

MattC
MattC el 27 de Feb. de 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 el 28 de Feb. de 2023
Editada: Stephen23 el 28 de Feb. de 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:

Iniciar sesión para comentar.

Más respuestas (1)

Cameron
Cameron el 27 de Feb. de 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 comentarios

MattC
MattC el 27 de Feb. de 2023
I added the code I developed with the for loop in Walter's comment. Can you please help me get all the values and not just the first one. I am not able to figure out what is wrong with my code
Cameron
Cameron el 27 de Feb. de 2023
If you want something more specific you'll need to post your data (your variable Data) and what you'd like to do with it.
So, the data I have looks something like:
(1x1 struct count (1) (parent struct)) - which again has (1x1 struct - count (5) (child struct)) - which finally has (1x100 tables count (3))
I am trying to build a for loop which can pass through both the parent and child struct variables and then get me to those 3 tables
Data Looks like:
MainData --> Name1 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
MainData --> Name2 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
MainData --> Name3 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
MainData --> Name4 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
MainData --> Name5 --> Table 1(1x100), Table 2(1x100), Table 3(1x100)
The reason behind building this loop dynamically is Name field or the second structure might or might not have 5 count. It might stop at Name3 or Name2. However, that is for sure that each name will have 3 tables. So, in my code below I could achieve getting the first name1 and its corresponding table 1 but I would like to fetch first how many names it has 1,2,3..5 and then fetch all the 3 tables
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
Hope this information helps
Stephen23
Stephen23 el 27 de Feb. de 2023
Editada: Stephen23 el 27 de Feb. de 2023
"Hope this information helps"
As far as I can tell, this means you would have 3x(number of fields in MainData) tables to store. How do you want to store them: in a cell array, or concatenating them together into three larger tables, or something else? Looping over structure fields is easy, but your question is not very clear because you have not specified what you want to do with those tables, e.g. how you want to store them.
Hopefully you are not planning on giving every table a unique variable name:
MattC
MattC el 27 de Feb. de 2023
Editada: MattC el 27 de Feb. de 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
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.

Iniciar sesión para comentar.

Categorías

Etiquetas

Preguntada:

el 27 de Feb. de 2023

Comentada:

el 28 de Feb. de 2023

Community Treasure Hunt

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

Start Hunting!

Translated by