Can't use user input and eval() to add a row to a table within a structure.

2 ビュー (過去 30 日間)
Andrew Hill
Andrew Hill 2021 年 11 月 11 日
コメント済み: Andrew Hill 2021 年 11 月 14 日
Hello Matlab community,
I'm pretty new to Matlab and to coding in general. I wrote some code that adds a row to one of two tables (tableA and tableB), but the table is selected by the user. In lieu of having the user type in 'myStruct.tableA,' I wanted the code to just take 'A,' and then I'd strcat() the rest, and then use eval() to call the correct table.
var1 = ["A"];
var2 = ["B"];
var3 = ["C"];
tableA = table(var1, var2, var3);
tableB = table(var1, var2, var3);
myStruct.tableA = tableA;
myStruct.tableB = tableB;
userInput = input('Which table would you like to add a row to (A or B)? ', 's');
T = strcat("myStruct.table",userInput);
newRow = {var1, var2, var3};
eval(T) = [eval(T); newRow];
When I do this, I get the following error:
Subscripting into a table using one subscript (as in t(i)) is not supported. Specify a row subscript and a variable subscript, as in t(rows,vars). To select variables, use t(:,i) or for one variable t.(i). To select rows, use t(i,:).
However, this works fine to call the table:
eval(T)
And when I don't use eval(), this does what I want:
myStruct.tableA = [myStruct.tableA; newRow]
So I'm a little confused, and the error message doesn't make much sense to me for this particular case. Any advice would be great. Thank you.

採用された回答

Dave B
Dave B 2021 年 11 月 12 日
編集済み: Dave B 2021 年 11 月 12 日
First of all, this is not a good way to do things. In general, if you find yourself using eval, you should stop and rethink the problem. Just search for eval up above in the Search Answers box and you'll see lots of pros saying don't do it! You should do that search, and you'll learn lots more about why it's bad, and what to do instead. But I'll answer your specific situation below.
Note: eval does have uses, or we it wouldn't be in MATLAB, but it's far more easy to misuse than to use correctly, so save this until you don't feel like a beginner and you'll know when it's appropriate (almost never).
Why did this particular use or eval fail? because you're trying to use the result of eval as a target for assignment. Consider what happens in a simpler, non table, case:
a=1;
b='a';
eval(b)
a = 1
eval(b)=2
eval = 1×97
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
whos % note this gets a list of variables in the workspace
Name Size Bytes Class Attributes a 1x1 8 double b 1x1 2 char eval 1x97 776 double
The expression eval(b)=2 has created a variable called eval, and put the value 2 into the index associated with the letter 'a' (the letter 'a' being the 97th character in ascii, i.e. double('a')). In other words this was equivalent to typing eval('a')=2, which is equivalent to typing eval(97)=2.
As I wrote above, it's strongly discouraged to use eval for something like this, and every seasoned MATLABber will give you that advice. But if you really felt complled to experiment, you'd want to put the equals sign inside the eval string:
eval(T + "=[" + T + ";newRow];") % I can't even bring myself to mark it as code, not pretty!
So if that's a bad solution, what should you do instead?
Well in this case it's pretty simple, because you can use a variable to index into a struct:
myStruct.("table" + userInput) = [myStruct.("table" + userInput); newRow];
An alternative, more general solution (just to illustrate the approach) might be to use indexing and a cell array instead of a struct:
thetables = {tableA tableB};
options = ["A" "B"];
if ~ismember(userInput,options)
% put an error here!
% what should we do here? prompt again? Should the script stop running?
else
thetables(userInput==options) = [thetables(userInput==options); newRow];
end

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

製品


リリース

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by