Anonymous reference to structures/variables?

15 views (last 30 days)
Is there a way to reference a struct or a variable without explicitly using the name?
For example if I want create structs whose name can vary via somehting like
eval(sprintf('Struct_%d = struct();', counterVar));
This will create a bunch of structs like Struct_1, Struct_2, .... etc
Now I want to edit the fields of struct 1, I can't just say Struct_1.dataField = 123; because that is hard coded to be Struct_1 and this might be Struct_23...
What I could do is continue to abuse eval and sprintf and just do eval(sprintf('Struct_%d.dataField = %d', counterVar, myData)); but I am curios whether I can just get some sort of generic handle or memory reference to that struct I just created so that I could just do h.dataField = myData; and have it correctly update the right struct.
  10 Comments
Guillaume
Guillaume on 3 Aug 2019
It may be that using a much flatter format such as a table would be a lot more practical. I.e. a table with variables: trial_number, input_number, datachunk_index, rawdata, ...
This would be much easier to filter data according to any of the property, e.g. all everything to do with 1st input:
filtered = thetable(table.input_number == 1, :)
this is much harder to do with a multilevel struct. With a table, you also get access to lots of grouping functions such as groupsummary.
Stephen23
Stephen23 on 7 Aug 2019
Edited: Stephen23 on 8 Aug 2019
"...this obfuscates trial names and replaces them with indices in the struct array, which sort of defeats the purpose"
In fact it lets you achieve a much more useful goal: separation of code and data.
Meta-data (e.g. test parameters, subject names, indices, etc.) are data, and data do NOT belong in variable names or fieldnames. Mixing (meta-)data into code (as fieldnames or variable names) makes accessing that (meta-)data slow, complex, and hard to debug.
Indexing is much more efficient, clearer, less buggy, and easier to debug. A flatter structure using indexing would be much easier to work with.

Sign in to comment.

Answers (2)

Steven Lord
Steven Lord on 2 Aug 2019
Edited: Steven Lord on 2 Aug 2019
Don't define variables with dynamic names. One alternate approach would be to create fields in a struct array dynamically. The name of the struct array wouldn't change, just the names of the fields. Let's create 5 random names consisting of the word 'mydata' followed by a number between 1 and 100.
x = randperm(100, 5);
names = "mydata" + x
Make a struct using those names.
for whichfield = 1:numel(names)
mystruct.(names(whichfield)) = whichfield;
end
mystruct
If you're using a release that predates the string class you'll need to build the names array differently, perhaps using sprintf or num2str inside the loop.
for whichfield = 1:numel(x)
thename = sprintf('mydata%d', x(whichfield))
mystruct2.(thename) = whichfield;
end
mystruct2
Let's see if mystruct has a field named mydata42, or just retrieve it if it does (and tell the user it doesn't if it doesn't.)
is42TheAnswer = isfield(mystruct, 'mydata42')
thedata = NaN;
try
thedata = mystruct.('mydata42');
catch ME
warning(['The mystruct struct does not have a field named ', ...
'mydata42. Returning NaN.'])
end
thedata
  4 Comments
Jacob Franklin
Jacob Franklin on 2 Aug 2019
The data is already manipulated fine, I just want organize it for saving to file that is human readable. ideally would name the file experiment_0000n_ddMMYYYY_hhmmss.mat and it will open up a DataStruct with trial structures containing input structures containing data chunk structures containg raw data and a metaStruct. The names of which would be variable, i.e. trial 1, inputs 0 to 3, dataChunks 1-N, etc.
So dynamic naming seems unavoidable. Even if I premade the structure I would still need the dynamic naming to access the correct substruct and field.
Stephen23
Stephen23 on 8 Aug 2019
Edited: Stephen23 on 8 Aug 2019
"I just want organize it for saving to file that is human readable"
Keeping meta-data and code separate is best in terms of code simplicity, efficiency, and ease of debugging. What you are trying to do makes your code more complex, liable to bugs, and less efficient, which has a direct negative effect on your productivity:
Making data "human readable" would be achieved using a simpler structure that makes it easier to process that data:
"So dynamic naming seems unavoidable."
I very much doubt that:
  • If you are exporting the data to a .mat file then you can use the '-struct' option.
  • No other file types store variable names, so the variable names are irrelevant.
"Even if I premade the structure I would still need the dynamic naming to access the correct substruct and field."
Yes. Better than dynamic variable names, although it still mixes up meta-data and code, forcing you to write slow and complex code. Indexing is much simpler.

Sign in to comment.


Walter Roberson
Walter Roberson on 2 Aug 2019
Use dynamic field names on a fixed variable name. Then save() with the -struct option. That will make the top level fields of the struct into separate variables in the mat file.

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!