Is it possible to extract all fields from a structure automatically?

I have data in the form: mydata.x = 100; mydata.s = 'abc'; mydata.Y = [1 2 3]; And I want variables x = 100; s = 'abc'; Y = [1 2 3]; How to extract variables automatically? (suppose that I don't know the names of the variables!)

7 Comments

What you want is to magically create new variables in your workspace without knowing what they are when you write the code. This is a really bad idea (slow, buggy, impossible to debug, etc), which had been explained to you before, in lots of your own questions:
Do you imagine that something has changed since you asked those questions? Why beginners love to use a programming method that removes so many useful tools and code checking is beyond my understanding.
The programming best practice would be to simply to use the structure. What is wrong with doing that ?
Please answer my question. Is it possible? How?
I know the variables, but I dont want to list them. I dont want to write hundreds of variables and name them in the code twice!
"Is it possible"
Of course it is possible. Clearly you didn't bother to read any of those links in your own questions, because they all explain how (or have links to an explanation). They also explain why it is very poor programming.
  • beginner: How can I magically create variables?
  • expert: don't do that, it is slow and buggy. Here are some better ways...
  • beginner: No! I am better than all of those professional programmers who have written advice to avoid doing this! Even those so-called experts at MATLAB who write that magically creating variables is a bad idea, they are just stupid. I am much more cunning than them!
  • expert: here are some much more reliable and easy ways to...
  • beginner: Haha!, I just created the variables magically!
  • expert: sigh.
One week later:
beginner: why is my code so slow? and I cannot fix these strange bugs...
Why does your structure have hundreds of variables in the first place? You should probably use an array or a table instead of a structure if you're going to need that many fields.
The basic situation for me is the following. I have lots of data in the same structure, but I cannot load them all at the same time, because one structure has GB size. So I save data in files like: data1.mat, data2.mat, etc. In the data save script I want to collect data in a structure, like
data.id = 1;
data.resolution = 0.01;
data.matrix = ...;
data.name = 'Alice';
data.vector = [...];
etc.
It has the advantage, that at the end of the script it is enough to save 'data' and no need to list and write variable names twice. After saving, I want to use data by using the load function. However I don't want to write data. before each variable, because it makes the code very ugly. So I want to convert the structure to set of variables. Are there any built in automatic method or I have to write a for cycle and find name of the variables of the structure etc.? For me this conversion will simplify my ode, however I want to keep the possibility to use the structure in other codes or for other coders.
Why anybody think that this is a dynamic variable in my example? I think this is simple loading problem and not dynamic variable.

Sign in to comment.

 Accepted Answer

You seem intent on magically making variables pop into existence in the workspace, so here is probably the least-worst way of doing that. The trick is to change the save command by adding the '-struct' option:
>> S.name = 'anna';
>> S.data = 1:3;
>> save('temp.mat','-struct','S')
and then load it like this:
>> clear
>> load('temp.mat')
>> name
name = anna
>> data
data =
1 2 3
and you will find all of those variables in your workspace.

More Answers (3)

Alternative, maybe this is more desired than dictating how the struct will be saved in the workspace (this will recursively unpack any struct within the struct):
function unpackStruct (structure)
fn = fieldnames(structure);
for i = 1:numel(fn)
fni = string(fn(i));
field = structure.(fni);
if (isstruct(field))
unpackStruct(field);
continue;
end
assignin('base', fni, field);
end
end

6 Comments

This has all the same problems as calling eval plus it creates the variables in the base workspace. This has many problems, among them a cluttered base workspace (making it difficult to find a particular needle in a huge haystack) and storing the data where any other function that runs can manipulate it, meaning you can't tell (without checking every single time) whether the data on which you're operating is the same as the data from your struct.
Makes sense. Also, I realized that I am not sure what will happen if a nested struct has the same field name with an existing variable in the workspace - I guess it will overwrite it. It's got flaws, agreed.
"It's got flaws..."
Slow, complex, obfuscated, liable to bugs (e.g. overwrites variables without warning, as you note), difficult to debug... Nothing new, the same as all other methods of dynamic variable accessing:
"I realized that I am not sure what will happen if a nested struct has the same field name with an existing variable in the workspace"
In fact this approach lets the data overwrite any variable in the code, not just the imported ones: data arrays, filenames, constant parameters, etc. can be overwritten without warning.
This method can be useful, but I recommend replacing assignin('base',... with assignin('caller',...
Or as a single anonymous function (which you can drop into your ide)
unpackStruct = @(s) cellfun(@(name) assignin('base',name,getfield(s,name)),fieldnames(s));

Sign in to comment.

Use fieldnames function
mydata.x = 100;
mydata.s = 'abc';
mydata.Y = [1 2 3];
field=fieldnames(mydata)
Then you want to assign to each variable individually a corresponding value, which is not recommended. Read this http://matlab.wikia.com/wiki/FAQ#How_can_I_create_variables_A1.2C_A2.2C....2CA10_in_a_loop.3F
Vibin
Vibin on 15 Nov 2024
Edited: Vibin on 15 Nov 2024
who / whos function when called without any argument, lists all the variables in the current workspace with their properties.

Categories

Asked:

on 10 Aug 2016

Edited:

on 15 Nov 2024

Community Treasure Hunt

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

Start Hunting!