views:

101

answers:

1

Is there a quick way (i.e. one line) to dump a collection of variables "in" a structure, using the variable names as the structure fields? The "load" function basically does this but saving and loading to a temporary file seems ugly.

For example:

clear
a = 'adsf'
b = rand(10);

x = var2struct(a,b)

x.a
x.b

or better yet:

x = var2struct(['a';'b'])

Also, what about the reverse (i.e. dumping the field values to the current scope as variables named after the fields)?:

clear
x.a='asdf'
x.b=rand(10);
dumpstruct(x)
a
b 

Also, here's a related newsgroup thread.

+11  A: 

Aside from using LOAD and SAVE, there is no built-in function that I know of to do this. However, you could just make your own functions, like so:

function s = var2struct(varargin)
  names = arrayfun(@inputname,1:nargin,'UniformOutput',false);
  s = cell2struct(varargin,names,2);
end

function struct2var(s)
  cellfun(@(n,v) assignin('base',n,v),fieldnames(s),struct2cell(s));
end

Working from the base workspace, you can use these functions like so:

a = 'adsf'
b = rand(10);
x = var2struct(a,b);
clear a b
struct2var(x);

A couple notes:

  • If you would rather specify the arguments to var2struct as the variable names instead of the variables themselves, here is an alternative function:

    function s = var2struct(varargin)
      values = cellfun(@(n) evalin('base',n),varargin,'UniformOutput',false);
      s = cell2struct(values,varargin,2);
    end
    

    And you would use this from the base workspace as follows:

    x = var2struct('a','b');
    

    Unfortunately, you can only use this version of the function to get variables from the base workspace, not the workspace of a function.

  • One caveat with the struct2var function above is that it will always create the variables in the base workspace, not the workspace of the function calling struct2var. To create variables in a workspace other than the base, you would have to use this line in that workspace instead of calling struct2var:

    cellfun(@(n,v) assignin('caller',n,v),fieldnames(x),struct2cell(x));
    
gnovice
Can't you use evalin('caller',n) for the second version of var2struct? Anyway, +1 for a beautiful solution that includes tons of advanced Matlab.
Jonas
@Jonas: using `evalin('caller',n)` for the second version of `var2struct` would actually perform the evaluation in the function that calls `evalin`, which would be `var2struct` itself and not the function that calls `var2struct`. That's why I like the first version of `var2struct` better... it just seems cleaner and more versatile.
gnovice
@gnovice: D'oh!. I remember now that I've made that mistake before.
Jonas
+1 very nice solution (I prefer the first approach)
Amro