Dynamically name a struct

I'm generating a GUI which users will type the name of a test and then generate structs based off of the test type. Right now they have 4 selections to choose from for struct naming (Body, Head, Leg, and New). I need this ability for the "New" element so that this code doesn't become useless when new test types are generated. (I'm only stating this because there are plenty of answers with naming struct fields that argue that I should never need to do this).
I have a temporary variable k, that holds the struct until the end, where I would like to essentially go (variable) = k, and have it generate
k.TestName k.SignalName k.Signals.. etc
(variable) = k;
(variable).TestName (variable).SignalName (variable).Signals.. etc
Any and all ideas would be greatly appreciated.
Best, ML

 Accepted Answer

Guillaume
Guillaume on 14 Dec 2015
Edited: Guillaume on 14 Dec 2015
While it is possible to generate variables dynamically (just use eval) it's not recommended practice. Generating the variable name from user input, particularly, is asking for trouble. The way variables work in matlab, they shadow functions of the same name. So if the user decides to name your variable plus, that's addition broken in the rest of your program, name it eq and it's comparison that's broken.
You also have no guarantee that the string entered by the user is a valid variable name. So you have to pass the user input through genvarname or matlab.lang.makeValidName, but then the actual variable name may be different from the user input. Possible confusion...
I'm not clear on your end goal, but if what you want is a mapping between an arbitrary (user input) string and a value then you could use a map. Matlab's implementation of maps is a bit clunky but it does work.

More Answers (2)

For your application of combining .mat files, you should use
structname = load(TheFile);
and combine the structs into other structs, and when the user inputs the name of a variable, pull it out of the combined struct using dynamic field names. When it comes time to write to a .mat file, use save() with the -struct flag.

4 Comments

Thank you but I'm still little confused.
So you are saying I run the code (which works) and end up with a struct k, that I then save, and then reload?
Is there no easier way to just rename a struct before saving it out? This code is a starter for other's and I'd like it to be consistent throughout. (Normally I could literally just say something like Body = k, and then I'd have a struct called Body that had all the right stuff in it at the end, I just need to be able to do that dynamically)
Example: User inputs either one of the normal names, or a new struct name Code does the same thing regardless but before saving out changes k to the correct struct name(aka the dynamic variable name)
User can then open the file with the correct name and use it going forward.
I am saying you should rewrite your code so that it does not ever refer to a user-named variable, and instead refers to a user-named field within a struct.
combined_struct = struct();
known_fields = sort(fieldnames(combined_struct));
...
this_file_struct = load('UserSelectedMatFile.mat');
these_fields = fieldnames(this_file_struct);
num_fields = length(these_fields);
for K = 1 : num_fields
this_field = these_fields{K};
combined_struct.(this_field) = this_file_struct.(this_field);
end
known_fields = sort(fieldnames(combined_struct));
set(handles.known_fields_popup, 'String', known_fields); %update user list
...
new_fieldname_user_chose = 'SuperSeiyan';
combined_struct.(new_fieldname_user_chose) = []; %create it
....
save('OutputFileName', 'combined_struct', '-struct');
The -struct flag instructs MATLAB to not save combined_struct as a variable and to instead create one variable in the .mat file for each field in combined_struct, pulling apart the structure into individual variables in the .mat file.
Like all 3 of us said, it's not a good idea to let your variable names be named according to what string your users type in.
Stephen23
Stephen23 on 13 Jan 2016
Edited: Stephen23 on 19 Jun 2019

Sign in to comment.

You know what they selected, right? Like if they typed it in or chose a radio button or picked it from a listbox or popup? So just assign the name based on what they chose. Let's say you have boolean variables head, body, etc. that say whether that body part was chosen or not. Then just do
if bodySelected
body = k;
elseif headSelected
head = k;
elseif legSelected
leg = k;
end

3 Comments

Mary
Mary on 14 Dec 2015
Edited: Mary on 14 Dec 2015
Yes, that would be easy, but the "New" part of this is where I'm running into the issue. I wont necessarily have a string until the user generates it. ( I have a radio button group that loads a uiinput box when they select New, so that they can type in a variable name)
Why do you let your users decide what your variable name in your program should be called? That does not seem like a wise idea.
The code takes .mat files of data and combines them into larger .mat files. The current code is already written, and I am trying to generate a new GUI which implements it allowing users (educated engineers who helped to collect the data and generate it in the first place), make tests which do not follow existing struct names.
The goal is that if new tests arise in the future, we can easily implement the code without having to go through an update it. Which is incredibly helpful on a large team with multiple projects.
I guess I'm seeking less of an opinion on whether or not I should do it, and more of a solution on if this is something possible.
I'm familar with switching out the field names, but dynamic variables seem to always get this response.
If it's something not possible I'll just try to work around it the best I can (or just write a description for individuals to change the code themselves (which I would rather not have happen)) so that they can generate a struct with the correct name they need.

Sign in to comment.

Categories

Asked:

on 14 Dec 2015

Edited:

on 19 Jun 2019

Community Treasure Hunt

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

Start Hunting!