Changing variable name from input string
54 views (last 30 days)
Show older comments
I have some code that processes experimental data of mine and saves a variable, Depth, to the workspace. I would like to include some lines that would ask the user for an input string, say NewName and use this as the name for Depth, while retaining all the data in the array. I'd rather not have to rename every instance of Depth in my code as I want to use this on other data sets and have unique names for the variable in each case.
So far I have:
prompt = 'What would you like to rename Depth?';
str = input(prompt,'s');
if (isempty(str) == 1)
str = 'Depth';
end
str = Depth;
so that if the input is empty, then Depth is not renamed. However, this only creates a new array str with the same values as Depth, and does not rename Depth or even create a new array, NewName, with the same values as Depth.
Is there any way to solve this or work around it?
2 Comments
Stephen23
on 9 Jan 2020
"Is there any way to solve this..:"
Yes, but only if you want to force yourself into writing slow, complex, obfuscated, buggy code that is hard to debug. Read this to know why:
":.. or work around it?"
Simply use a container array: a cell array, a structure, a table, etc.
Adam Danz
on 9 Jan 2020
Edited: Adam Danz
on 9 Jan 2020
In case you need a second opinion, Stephen is, of course, correct that this type of dynamic variable naming will open a can or worms. Here's a quick example of how you can store the user's variable name.
prompt = 'What would you like to rename Depth? '; % add space at end
str = input(prompt,'s');
if isempty(str) % no need for equality testing
str = 'Depth';
end
varnames{n} = str; % store the variable name in a cell array
vars{n} = value; % store the values for that variable is a 2nd cell array
Now when you want to access the variables.
varIdx = strcmp(varnames, 'Depth');
vars{varIdx}
Answers (3)
Steven Lord
on 9 Jan 2020
Rather than using eval or storing your "variable names" and your values separately, if the names are valid MATLAB identifiers you could store them in a struct array using dynamic field names.
mydata = struct();
for k = 1:10
name = "Variable" + k;
mydata.(name) = k.^2;
end
mydata
If they're not valid MATLAB identifiers and you're using release R2019b or later you could store your data in a table array. Alternately you could use a containers.Map to store the data with each "variable name" as the key.
3 Comments
Steven Lord
on 9 Jan 2020
Using a cell array would work, but it does require the users to strcmp when retrieving data and runs the risk of have two sets of data with the same name in the cell array. If you were to store the names and data in a cell array with two columns (first for names, second for data) rather than two separate cell arrays you'd also reduce the chances of the names and data arrays getting out of sync (adding a name to the name cell but forgetting to update the values cell or vice versa, for example.)
Adam Danz
on 9 Jan 2020
Edited: Adam Danz
on 9 Jan 2020
The two column cell array would definitely be better than having two variables. The input name could also be checked for uniqueness.
isNotUnique = true;
prompt = 'What would you like to rename Depth? ';
C = {'a', 1:5; 'b', 2:10};
values = 5:50; % the values that will be associated with new variable
% Keep asking for variable name until the name is unique
while isNotUnique
str = input(prompt,'s');
isNotUnique = ismember(str,C(:,1));
prompt = 'Variable name taken. Choose a unique name. ';
end
% Store new variable
C(3,:) = {str, values};
Adam Danz
on 9 Jan 2020
Edited: Adam Danz
on 9 Jan 2020
For visibility, I've summarized my comments here as an answer.
This demo asks the user for a variable name and stores the variable name along with the associated values in an nx2 cell array with the variable names in column 1 and values in column 2. If the variable name is taken or empty, the user will be prompted again to create a variable name. The variable name can unconventionally be any combination of characters.
prompt = 'What would you like to rename Depth? ';
C = {'a', 1:5; 'b', 2:10}; % nx2 array of {variableNames, values}
values = 5:50; % This is the value we're currently naming
isNotUnique = true;
% Ask user for a unique, nonempty variable name
while isNotUnique
str = input(prompt,'s');
isNotUnique = ismember(str,C(:,1)) || isempty(str);
prompt = 'Variable name taken or was empty. Choose a unique name. ';
end
% Store new var-name and it's associated value
C(3,:) = {str, values};
% or C(end+1,:) = {str, values};
To access the case-sensitive variable named 'a' by the user,
C{strcmp(C(:,1), 'a'),2}
To access the n_th variable
C{n,2}
0 Comments
Ruger28
on 9 Jan 2020
Chiming in for a 3rd opinion. I have used this in the past succesfully.
Depth = [1:100];
prompt = 'What would you like to rename Depth?';
str = input(prompt,'s');
if ~isempty(str)
eval([str, ' =Depth;']); % rename if there is a string
end
4 Comments
Ruger28
on 9 Jan 2020
Stephen - I use the method of structures, but I was simply answering the OP's question the way they described their issue and desired outcome.
Adam Danz
on 9 Jan 2020
Yes, but the point is to steer the OPs away from bad practices. It's the XY problem. The OP is asking for a solution that s/he thinks is a good solution to the problem. But focus should be placed on the problem itself, not on what the OP thinks the best solution is to the problem.
See Also
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!