Collect variables in structure with corresponding fieldnames

I'm looking for an easy way to achieve the following:
X=struct();
X.a = a;
X.b = b;
X.c = c;
(and so on)
Here, a,b, and c are workspace variables (could be scalars, cells, strings or structures themselves)
The reason that the above syntax is not acceptable is that I have many variables to collect in my structure X, and the code would get very long using the above syntax.
Your help is greatly appreciated!

Answers (3)

Why is long code not acceptable, if it is efficient, safe, easy to read and to debug?
Another method, which is not remarkably shorter:
X = struct('a', {a}, 'b', {b}, 'c', {c});
The curly braces are required to consider cells also, otherwise a struct array is created.
The function FEX: WorkspaceToStruct stores all variables of the current workspace to a struct. While this could be an overkill for your problem, the code could be useful after some adjustments.
[EDITED after Yoel's comment] Simply use a list of the names of the variables as input instead of calling WHOS:
function S = ws2struct(varargin)
vars = varargin;
for iv = 1:numel(vars)
S.(vars{iv}) = evalin('caller', vars{iv});
end
Now call this as:
S = ws2struct('a', 'b', 'c');
But I definitely do not recommen to use this, because EVALIN() is brute and if the input contains a command, it is evaluated. In addition this only hides inside a subfunction, what you have done explicitely and clearly in the main function already. Even if you use this loop in the main function, the necessary EVAL() command is prone to problems. Therefore I still prefer:
X.a = a;
X.b = b;
X.c = c;
...

1 Comment

Can you please elaborate on the need for curly braces? What situation fail when the curly braces aren't present? Thanks.

Sign in to comment.

You can define
function x = fcn(varargin)
x = struct;
for ii = 1:nargin
x.(inputname(ii)) = varargin{ii};
end
end
a = 1;
b = 1:10;
c = {'a', 3};
X = fcn(a,b,c)
X=
a: 1
b: [1 2 3 4 5 6 7 8 9 10]
c: {'a' [3]}

4 Comments

INPUTNAME has its drawbacks, but I like it much more than EVALIN. +1
What are the drawbacks to INPUTNAME?
Yoel Lex wrote [Comment moved from the Answers section]:
Very nice, thank you!
I was unaware of the existence of the inputname function. That makes it quite easy!
1. The INPUTNAME is empty for temporary objects, e.g. in your program "fcn(a, b(1))". This is obvious and trivial, but prone to errors.
2. INPUTNAME encourages programmers to mix names of variables with their data, see e.g. http://www.mathworks.com/matlabcentral/newsreader/view_thread/317562 .
Both are _drawbacks_, which cannot compete with the debugging horror caused by EVAL.

Sign in to comment.

http://www.mathworks.com/matlabcentral/fileexchange/36257-save-workspace-to-struct does not really solve the problem. I relies on getting the list of workspace variables using 'who', whereas I would like function where I feed in the variables, e.g.
X = fcn(a,b,c)
which would produce
X.a = a
X.b = b
X.c = c
It's not obvious to me how to adapt the function on the above linke to achieve that.

Categories

Asked:

on 18 May 2012

Commented:

FM
on 27 Jun 2018

Community Treasure Hunt

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

Start Hunting!