问题
I find it impossible to write MATLAB code without creating a huge number of superfluous, single-use variables.
For example, suppose function foo
returns three column vectors of exactly the same size. Say:
function [a, b, c] = foo(n)
a = rand(n, 1);
b = rand(n, 1);
c = rand(n, 1);
end
Now, suppose that bar
is a function that expect as imput a cell array of size (1, 3)
.
function result = bar(triplet)
[x, y, z] = triplet{:};
result = x + y + z;
end
If I want to pass the results of foo(5)
, I can do it by creating three otherwise-useless variables:
[x, y, z] = foo(5);
result = bar({x, y, z});
Is there some function baz
that would allow me to replace the two lines above with
result = bar(baz(foo(5)));
?
NB: the functions foo
and bar
above are meant only as examples. They're supposed to represent functions over which I have no control. IOW, modifying them is not an option.
回答1:
Not possible. baz
in baz(foo(5))
will only take the first output of foo
, the other two would be ignored. The plain two-line variant is not that awkward. And this is not a common situation. You don't generally work with cell arrays where normal numerical arrays would do.
You could of course just write your own wrapper for foo
that returns whatever you need (i.e. containing similar two lines), in case you need to use it frequently.
回答2:
You can replace the three variables by a cell array using a comma-separated list:
vars = cell(1,3); % initiallize cell array with as many elements as outputs of foo
[vars{:}] = foo(5); % comma-separated list: each cell acts as a variable that
% receives an output of foo
result = bar(vars);
回答3:
As nirvana-msu said, it is not possible to do the task without creating temporary variables. But it is possible to handle it within a function and even with varargin
and varargout
. Inspired by this answer on my question, you can define and use the following function:
function varargout = redirect(F1, F2, count, list, varargin)
output = cell(1, count);
[output{:}] = F2(varargin{:});
varargout = cell(1, max(nargout, 1));
[varargout{:}] = F1(output(list));
end
For instance, in your example you can write result = redirect(@bar, @foo, 3, [1:3], 5);
回答4:
The issue is you are converting the cell triplet{} into an array[], so a conversion is the method you want. Although this method will perform the inverse transformation, I know of no method that will perform the transformation you want, likely due to the relative complexity of the cell data structure. You may have some luck further digging into the API.
EDIT: EBH kindly pointed out this method, which does what you are looking for.
EDIT2: The above method will not perform the action OP asked for. Leaving this up because the API often has great solutions that are hidden by bad names.
来源:https://stackoverflow.com/questions/38213814/how-to-force-matlab-to-return-all-values-in-a-nested-function-call