If a MATLAB function returns a variable number of values, how can I get all of them as a cell array?

function, matlab

Solution

You have to use `()` instead of `{}` to index the cells:

function left = remove(cells, item)
  left = cells(cellfun(@(i) ~isequal(item, i), cells));

Using `()` for indexing will give you a subset of cells, while using `{}` will return the contents of a subset of cells as a comma-separated list, and only the first entry of that list will get placed in `left` in your example.

You can check out this MATLAB documentation for more information on using cell arrays.

EDIT: Response to comment...

If you have an operation that ends up giving you a comma-separated list, you can place the individual elements of the list into cells of a cell array by surrounding the operation with curly braces. For your example, you could do:

left = {cells{cellfun(@(i) ~isequal(item, i), cells)}};

The inner set of curly braces creates a comma-separated list of the contents of `cells` that are not equal to `item`, and the outer set then collects this list into a cell array. This will, of course, give the same result as just using parentheses for the indexing, which is the more sensible approach in this case.

If you have a function that returns multiple output arguments, and you want to collect these multiple values into a cell array, then it's a bit more complicated. You first have to decide how many output arguments you will get, or you can use the function NARGOUT to get all possible outputs:

nOut = 3;                   %# Get the first three output arguments
%# Or...
nOut = nargout(@some_fcn);  %# Get all the output arguments from some_fcn

Then you can collect the outputs into a 1-by-`nOut` cell array `outArgs` by doing the following:

[outArgs{1:nOut}] = some_fcn(...);

It should be noted that NARGOUT will return a negative value if the function has a variable number of output arguments, so you will have to choose the value for `nOut` yourself in such a case.

Problem

I am writing a function to remove some values from a cell array, like so: ``` function left = remove(cells, item); left = cells{cellfun(@(i) ~isequal(item, i), cells)}; ``` But when I run this, `left` has only the first value, as the call to cells{} with a logical array returns all of the matching cells as separate values. How do I group these separate return values into a single cell array? Also, perhaps there is already a way to remove a given item from a cell array? I could not find it in the documentation.

Original source