How to elegantly ignore some return values of a MA

2019-01-02 23:30发布

Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?

Let's say, I have the following function in MATLAB:

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;

Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;

But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:

[_, _, variableThatIWillUse, _] = func;

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

Are there any elegant ways to do this that do work?


So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;

I still think this is very ugly code, but if there is no better way, then I guess I'll accept the answer.

8条回答
forever°为你锁心
2楼-- · 2019-01-02 23:44

If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is

[ans,ans,variableThatIWillUse] = myfun(inputs);

ans is of course the default junk variable for matlab, getting overwritten often in the course of a session.

While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code. I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.

查看更多
ら.Afraid
3楼-- · 2019-01-02 23:51

This is somewhat of a hack but it works:

First a quick example function:

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3

Now the key here is that if you use an variable twice in the left hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:

[b,b,c]=Func3();
% yields b=2, c=3

[c,c,c]=Func3();
% yields c=3

(edit: just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the 3rd argument)


edit: there's a better approach; see ManWithSleeve's answer instead.

查看更多
Root(大扎)
4楼-- · 2019-01-02 23:52

With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,

[~, ~, variableThatIWillUse] = myFunction();

Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.

See the release notes for details.

查看更多
甜甜的少女心
5楼-- · 2019-01-02 23:55

I wrote a kth out function:


function kth = kthout(k,ffnc,varargin)
%% kthout: take the kth varargout from a func call %FOLDUP
% 
% kth = kthout(k,ffnc,varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

[outargs{1:k}]  = feval(ffnc,varargin{:});
kth                         = outargs{k};

end %function

you can then call

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc

you could also wrap up the function like

func_i_want = @(varargin)(kthout(3,@myfunc,varargin{:}));  %assuming you want the 3rd output.

after which you use

val_i_want = func_i_want(func_input_1,func_input_2);

note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.

查看更多
你好瞎i
6楼-- · 2019-01-02 23:56

Is there any reason not to use ans(n), like this:

a=rand([5 10 20 40]);

size(a);

b=ans(2);

Gives b = 10, and would this way not be compatible with all Matlab versions?

Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:

[~, b] = size(a);

Then b = 8000 ! (You need to end with ~, to catch more arguments!)

查看更多
混吃等死
7楼-- · 2019-01-02 23:58

You can make a function (or anonymous function) that only returns selected outputs, e.g.

select = @(a,b) a(b);

Then you can call your function like this:

select(func,2);
select(func,1:3);

Or you can assign the output to a variable:

output(1,2:4) = select(func,1:3);
查看更多
登录 后发表回答