Generate Field Names from Variables While Accessing Elements of a Nonscalar Structure Array

I have a top-level 1x20 structure arrray with 10 fields which is generated using code similar to below with no problems (this is an extract of a larger script).
for nLap = 1:R2(nDriver).Laps
R2(nDriver).LapData(nLap).LapTime = sessions.R2.Sectors.(nDriverStr).LapTime(nLap);
R2(nDriver).LapData(nLap).SectoR2 = sessions.R2.Sectors.(nDriverStr).S1Time(nLap);
R2(nDriver).LapData(nLap).Sector2 = sessions.R2.Sectors.(nDriverStr).S2Time(nLap);
R2(nDriver).LapData(nLap).Sector3 = sessions.R2.Sectors.(nDriverStr).S3Time(nLap);
R2(nDriver).LapData(nLap).TIS = sessions.R2.Sectors.(nDriverStr).TiS(nLap);
end
However, I need to run this for many other structures by replacing the 'R2' to 'R1' for example.
Previously, I have done that in the same way that the (nDriverStr) variable in used to enter a field within the structure, however this does not seem to work when I am already referencing a row within the structure such as:
(R)(nDriver).LapData(nLap).LapTime = sessions.(R).Sectors.(nDriverStr).LapTime(nLap);
Is there a way to do this using R as a variable string which loops through "R1", "R2", "R3" for example?

4 Comments

"Generate Field Names from Variables..."
is the title, yet the question seems to be about how to generate dynamic variable names.
"However, I need to run this for many other structures by replacing the 'R2' to 'R1' for example. "
"Is there a way to do this using R as a variable string which loops through "R1", "R2", "R3" for example?"
Yes, there are certainly ways to do this, if you really want to force yourself into writing slow, complex, inefficient, obfuscated, buggy code that is hard to debug:
By forcing meta-data (in this case pseudo-indices) into the variable names you just made accessing your data much harder.
In contrast, if you had used actual indices then the solution would be simple and very efficient. You should use indexing: import those tables in one cell array and looop over that. Don't make your code more complex.
I doubt that you wrote out the names of all of those tables by hand, so you forgot to tell us the most important information: how did you get all of those (badly-named) tables into the workspace?
Thanks for the quick answer.
Your response has actually triggered the answer for me already; all the 1x20 structures should be contained within a top-level structure already, similar to the right hand side of the arguments above? i.e.
sessions.(R)(nDriver).LapData(nLap).LapTime = sessions.(R).Sectors.(nDriverStr).LapTime(nLap)
Wrt to the second question (I doubt that you wrote out the names of all of those tables by hand, so you forgot to tell us the most important information: how did you get all of those (badly-named) tables into the workspace?), a couple of questions from my side:
  1. What about the naming here makes these badly named?
  2. The tables are imports from csv (which in themselves are tables extracted from PDFs using python) which have been formatted into tables contained within structures. I am currently experimenting with an alternative way of storing them. This extract of code is part of a conversation between my old style and new style (both pictured). Do you think this is a poor way of storing data? Structures are new to me but when I found them, they seemed to be the most natural way of storing this data.
Old
New
"What about the naming here makes these badly named?"
Forcing pseudo-indices into variable names mixes (meta-)data into your code, with the end result of forcing yourself into writing slow, complex, inefficient, insecure code when trying to access that data:
Using pseudo-indices in fieldnames or variable names (e.g. "R1", "R2", etc) is almost always better replaced with actual indices into one array. When you see yourself adding numbers onto field/variable names, you must ask yourself if those are pseudo-indices (slow and complex) that should be actual indices (simple and very efficient).
" Structures are new to me but when I found them, they seemed to be the most natural way of storing this data."
In my opinion, structures are a great way to store imported data, because they make it easy to store the improted data together with any assocaited meta-data (e.g. filenames, test information, etc). But rather than nesting more structures by dynamic fieldnames using some meta-data, it is often better to use a structure array and fixed fieldnames, e.g.:
S(1).data = ..
S(1).name = ..
S(1).test = ..
S(2).data = ..
S(2).name = ..
S(2).test = ..
etc.
This makes looping over them simpler and very efficient, and it also means that you can use comma-separated lists:
"... am currently experimenting with an alternative way of storing them."
Keep experimenting!
What about the naming here makes these badly named?
Little "Bobby Tables". You're basically requiring arbitrary code execution. As a benign example:
name = 'why, x'; % Specified by user or written as a file name?
eval([name '.foo = 1'])
To satisfy a hamster.
x = struct with fields:
foo: 1
Now picture a system or quit call in place of the why call.

Sign in to comment.

Answers (1)

Why not a 2D struct array,
R(nDriver,1).LapData(nLap).LapTime
R(nDriver,2).LapData(nLap).LapTime
R(nDriver,3).LapData(nLap).LapTime

Categories

Products

Release

R2022a

Asked:

on 30 Jun 2022

Edited:

on 30 Jun 2022

Community Treasure Hunt

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

Start Hunting!