Unpack structure, only some fields

16 vues (au cours des 30 derniers jours)
Alessandro Maria Marco
Alessandro Maria Marco le 27 Fév 2023
Modifié(e) : Stephen23 le 27 Fév 2023
Suppose I have the structure par with fields
par.a=3.5;
par.b=[4;1.2];
par.c='ale';
I want to create variables b and c such that b=par.b and c=par.c. To do this, I wrote a simple function and I type
clear
par.a=3.5;
par.b=[4;1.2];
par.c='ale';
[b,c] = unpack(par,{'b','c'}); %too long, I don't wanna pass {'b','c'}
disp(b)
4.0000 1.2000
disp(c)
ale
function varargout = unpack(par,varnames)
nvar = numel(varnames);
varargout = cell(nvar,1);
for i=1:nvar
varargout{i} = par.(varnames{i});
end
end
This does what I want. However I would like to type simply
%[b,c] = unpack(par);
and NOT
%[b,c] = unpack(par,{'b','c'});
Is it possible to modify my function so that I don't have to give the names of the fields that I want to extract as a second input? When you have to unpack many variables it can be tedious.
Any help would be greatly appreciated!
  1 commentaire
Steven Lord
Steven Lord le 27 Fév 2023
Can you dynamically create variables from a struct array with names generated from the names of the fields? Yes.
Should you do this? The general consensus is no. That Answers post explains why this is generally discouraged and offers several alternative approaches.
For example, suppose your struct array had a field named exit. If you ran your code in a function file then tried to access that variable, well, don't try it if you have any unsaved variables in your workspace that you want to keep.
If you believe you have a use case where you need to do this that's not covered in the Answers post I linked above, please explain what you're hoping to do with those dynamically created variables.

Connectez-vous pour commenter.

Réponse acceptée

Walter Roberson
Walter Roberson le 27 Fév 2023
You are expecting that your function will be able to look at the names of the output variables in the caller, and figure out from those which fields to extract and which order.
In MATLAB, the only way to figure out the name of the output variables is to use dbstack to find which line of which file is executing, and have the function read the source code for that function and parse it to figure out what the variable names are.
One of the volunteers (I think it might have been Jan) wrote code that tries to do something similar for the purpose of providing more informative error messages. It turned out to be a bit complicated. And if I recall correctly, he was not able to handle the case where the same function was called more than once on the same line.
There is no matlab call similar to inputname() but for output variables.
  2 commentaires
Alessandro Maria Marco
Alessandro Maria Marco le 27 Fév 2023
Thanks for the explanation! Yes, this is exactly what I wanted:
You are expecting that your function will be able to look at the names of the output variables in the caller, and figure out from those which fields to extract and which order.
I agree that it's not safe to use dbstack.. I guess that I'll stick to the function "unpack" that I have already. That should be ok, right?
Stephen23
Stephen23 le 27 Fév 2023
Modifié(e) : Stephen23 le 27 Fév 2023
"That should be ok, right?"
Sure, quite okay. You could use VARARGIN to avoid the cell array:
par.a = 3.5;
par.b = [4;1.2];
par.c = 'ale';
[b,c] = myunpack(par,'b','c') % no cell array
b = 2×1
4.0000 1.2000
c = 'ale'
function varargout = myunpack(S,varargin)
varargout = varargin; % simpler preallocation :)
for k = 1:numel(varargin)
varargout{k} = S.(varargin{k});
end
end

Connectez-vous pour commenter.

Plus de réponses (1)

Fangjun Jiang
Fangjun Jiang le 27 Fév 2023
Modifié(e) : Fangjun Jiang le 27 Fév 2023
make use of fieldnames()?
Avoid using the unpack() name. There is a built-in function with the same name.
par.a=3.5;
par.b=[4;1.2];
par.c='ale';
fieldnames(par)
ans = 3×1 cell array
{'a'} {'b'} {'c'}
  1 commentaire
Alessandro Maria Marco
Alessandro Maria Marco le 27 Fév 2023
This doesn't create the variables b and c. It only creates a cell array of characters where each character is the name of the fields of par. I would like smth [b,c]=unpack(par) where b and c are newly created variables

Connectez-vous pour commenter.

Catégories

En savoir plus sur Debugging and Analysis dans Help Center et File Exchange

Produits


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by