Convert char to variable

Hello all,
I have a huge cell array with countries and their covid19 incidence.
I would like to use those 'chars' to directly create the objects whose names are the country names within my previously defined Class. Is there a ways to convert those chars to used them as variable or object name?
Thanks in advance for any hint.

7 个评论

Ive J
Ive J 2021-1-2
编辑:Ive J 2021-1-2
Just don't. This has been discussed at length here.
There are better ways to do it (above link).
Hello Ive, Thanks for your reply. Sorry, I've doing around with MATLAB only two months now. I am really new to this and struggling with OOP. Yes, I want to create objects corresponding to each one of the countries and I already tried by creating a vector with the number of objects I want to create, but that did't work. If I should avoid eval and I kind of understand why, could you please let me know which strategy you recommend? Sorry, but reading the thread brought more confusion to me.
"xIf I should avoid eval and I kind of understand why..."
The problem is not eval in particular, the problem is dynamically accessing variable names:
"...could you please let me know which strategy you recommend?"
Very simple: data should be stored in variables, not in variable names, fieldnames, or the like. Note that meta-data, such as country names, test numbers, etc., is data. In order to use MATLAB efficiently and easily, simply keep all data together as much as possible in arrays and minimize pointless duplication into new arrays. For example, your data are neatly contained in a cell array, where they can be trivially accessed using basic indexing (e.g. in a loop) or many function applied to the entire cell array at once (e.g. string comparisons, regular expressions, etc.). If you split up the data into lots of little separated variables you make accessing and processing your data much harder.
Instead of asking about how to name variables, tell us what you are actually trying to do with this data:
Hello Stephen,
thanks for your repply. I now realize I was not being clear about what my task is and what I am trying to do, maybe because I don't want to get spoon fed the answer so I might be a bit clumsy trying to present the case. I will bold the key words.
I am given Covid19 data by country and by some regions of those countries. The data is available in an cell array, in such way that the first row represents the dates, the first column represents the countries and the second column represents the regions of the countries (in case the data are available), as you will certainly see clearly in following screenshot. The 1x2 arrays in the single cells represent the postive and death cases in the corresponding countries and/or regions:
The requirement of the assigment is, by means of OOP, to create an app that reflects the data with widgets. At this moment what the app should exactly reflect is not relevant. So, it is necessary to create objects that contain the data and for that I need to define a class, which I called country (duh). Roughly, my class is:
classdef country
properties
Name
BelongsTo
Regions
PositiveCases
DeathCases
end
end
Name is obviously the Name of the country, BelongsTo is the region the country object belongs to, i.e., BelongsTo = World if it is a souvereign country like Chile, or Canada if it is a region/state like Ontario (included in Regions). Global (or World) should an object that contains all the world covid19 cases data( PositiveCases and DeathCases). The same class should be enough to define all objects, regardless if those are world, any country or any region/state of the country. so the USA belong to world and include also all states and some overseas territories. The included regions should be contained in an array of objects, since because the app should be able to plot the covid19 cases by countries and by regions with the appropriate widgets, which is the reason I need to break down the data in objects, as the assigment specifies.
By the way, Stephen, you also repplied to my post on recursion last week and I am very thankful to you. I would like to get a hint on how to approach the creation of the objects to be able to work with the widgets. I tried to declares vectors with the corresponding sizes to allocate the objects. I could create an array containing all the countries, but when I tried to use that array to create the correspoding country objects I got an error. The problem I am facing now is how to create the objects with loops, since the code must be adapted to different sizes of the input data. Maybe should I allocate a cel instead of a vector? Can a vector or array consist of objects?
BR,
I think you'd just make an array of classes where each class has the name as a property, something like (untested)
allCountryData = country(yourCellArray);
and the constructor would use your cell array to make an array.
fprintf('Country 51 is %s.\n', allCountryData(51).name);
Or something like that. Just a guess - haven't tried it. Or maybe it's
allCountryData = country.construct(yourCellArray);
where you have to explicitly create a method called construct that takes yourCellArray and makes an array of classes out of it.
"Can a vector or array consist of objects?"
Of course:
Accessing that array will be much much simpler than messing around with dynamic variable names (as Walter Roberson's answer shows, dynamically defining variable names based on input data is very fragile and liable to latent bugs... it is also inefficient and difficult to debug). Keeping your data (of any class) in arrays is by far the best way to use MATLAB.
BelongsTo is the region the country object belongs to, i.e., BelongsTo = World if it is a souvereign country like Chile, or Canada if it is a region/state like Ontario (included in Regions)
Consider São Tomé and Príncipe which is a country in Central Africa. Imagine that somehow you managed to get around the problem that MATLAB variable names cannot contain characters such as space or ã or é or í -- imagine that you found a hack that permitted you to do that. Now, São Tomé and Príncipe is a sovereign country so according to what you said, BelongsTo must be World . But if so, then how are you going to link it into the Region object for Central Africa as shown in line 57 of your data file?

请先登录,再进行评论。

 采纳的回答

per isakson
per isakson 2021-1-2
编辑:per isakson 2021-1-2
"by means of OOP, to create an app"
Object Oriented Design isn't easy and there are many different solutions to a problem.
I would use a top-down approach
  • Make a sketch with paper and pencil of the GUI (I assume that the word "app" implies a GUI and that you should use Matlab's App Designer). Imagine how the user shall use the GUI and what results the user shall see. Make notes.
  • Google design pattern model view controler, MVC.
  • Spend ten minutes with youtube on Class Responsibility Collaboration, CRC (or similar)
  • Write a few CRC-cards and try hard to imagine how these classes would solve the problem. Try again. At this stage it is cheap to make changes.
  • Now it's time to start Matlab.
A comment on your proposed class. The properties, BelongsTo and Regions irk.
classdef Land
% Land is a portion of the earth's solid surface distinguishable by boundaries or ownership.
% Words are important and difficult to find. I search a noun that includes both country and
% region
properties
Name
PositiveCases
DeathCases
Children
end
end
Both countries and regions would be represented by objects of Land. Here the value of Children would be an array of Region-objects (, which could have Childrens like cities).
"Can a vector or array consist of objects?" Yes, object of the same class (and see matlab.mixin.Heterogeneous class)

更多回答(1 个)

C19T = readtable('covid_data.xlsx');
mask = cellfun(@isempty, C19T.State);
C19T.BelongsTo(mask) = {'World'};
C19T.BelongsTo(~mask) = C19T.Country(~mask);
C19T.Name(mask) = C19T.Country(mask);
C19T.Name(~mask) = C19T.State(~mask);
for R = 1 : height(C19T)
name = C19T.Name(R);
assignin('base', name, country(C19T.Country(R), C19T.BelongsTo(R)));
end
This fullfills your requirement to create seperate objects whose names are the country names (or state name as appropriate) to hold data.
If you test it , you will find that it crashes when it gets to Nova Scotia or Central Africa, as it is not possible in MATLAB to create a variable name which has a space in it.
To work around this, you will need to use a MATLAB release that is something like 10 or 15 years old, and use a mex file to create a variable with the corrupt name. All current releases check variable names carefully and refuse to create such variables, but old enough versions were sometimes lax on the checking and it was possible. However, you would need to do some testing to find out whether you can find an old version that was lax enough and which also had the modern classdef system of class definitions.
Using a variable with a corrupt variable name such as that is going to be difficult.
You will also have problems if any of the country names contain non-Latin characters such as España or Sudán .

产品

版本

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by