views:

2385

answers:

7

I was wondering if it was 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 that I'm only interested in the third return value. This can be accomplished by creating (at least) one dummy variable, but I think this is kind of ugly:

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

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 polutes the workspace (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.

Thanks for your time!

+2  A: 

<EDIT> The original answer assumes you have control over the function definition. It is not applicable in the case of using ready made functions.

As far as I know, With library functions you are stuck with either

retValues = func;
iUseThisOne = retValues(3);

or using separate dummies and clearing them. </EDIT>

If you know you will always ignore the same values, you can reorder the return variables so that the interesting values are set first, and those most likely to be ignored as last.

Say you had

function[a,b,c] = func()

and you are only interested in a.

Just use

[a] = func;

If a is the parameter to be ignored, consider changing the return order:

function[b,c,a] = func()

Now to only exclude a, you would do:

[b, c] = func;

Sources:

http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/br2js35-1.html

Jukka Dahlbom
The assumption that you can change the return order is a little far-fetched.
Jason S
(ok if you're writing your own function but the OP is almost certainly talking about a function that already exists)
Jason S
I don't find it far fetched to be defining your own functions. However your implied point is correct in that most functions you use in MATLAB are not your own.
Jukka Dahlbom
noted... downvote removed.
Jason S
+4  A: 

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)

Jason S
Had not thought about solving it like this. However, I feel this solution sacrifices the clarity of intent for cleverness.
Jukka Dahlbom
I personally just use [junk, junk, c] = function_call() and assume both that "junk" is never an important variable and if it contains a lot of memory that I will clear it if necessary.
Jason S
Same here, back when I used to work with MATLAB.
Jukka Dahlbom
+6  A: 

Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

Then call the function as follows:

[a{:}] = func();

Then simply remove the element from a that you want, and overwrite a:

a = a{3};  % Get the third output
gnovice
+10  A: 

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.

woodchips
+1: that's clever.
Jason S
Yes, it's clever, but the native Matlab editor will give a warning if you assign anything to the ans variable. I don't think having warnings are very elegant...
Jordi
You can turn the warning off.End the line with this comment string %#okMlint will then ignore this. No warnings.
woodchips
+1  A: 

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.

shabbychef
+27  A: 

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

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

See the release notes for details.

ManWithSleeve
Kind of annoying that it isn't "_". (I suppose that was taken already?)
SamB
A: 

In Matlab 2010a, I found a neat way of doing what you are asking for. It is simply to use the characher "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data. I don't know if this existed in previous versions, but I just came across it recently.

Sam
Didn't you see the previous answer?
yuk

related questions