Is there a functional form in Matlab to get the same result as A{:}?

109 Views Asked by At

I understand this is a classic question and some aspects of it have been answered before, for instance here: How can I index a MATLAB array returned by a function without first assigning it to a local variable?

But reading through the comments it has become clear that i) some of the proposed solutions don't work anymore (the ones based on builtin or feval) or ii) don't work for certain classes or indices.

Specifically for a cell array A, the results of A{:} and subsref(A,substruct('{}',{':'})) are not the same.

For the sake of completeness, I'd like to point out that cell2mat(A) is not the same as A{:} and does not help either.

To clarify further why this is relevant, if A was just a variable there would be no need for subsref. However, if A is a more general expression such as B{1} or C(1) etc, Matlab does not let you further index it with {:}.

A minimal working example showing the problem:

A=arrayfun(@(x) rand(2,2,2),ones(3,1),'Uni',0)
cat(4,A{:})

compared to:

cat(4,subsref(arrayfun(@(x) rand(2,2,2),ones(3,1),'Uni',0),substruct('{}',{':'})))

which only works on the first element.

2

There are 2 best solutions below

12
Luis Mendo On

I tested in R2019b and subsref(A,substruct('{}',{':'})) seems to return the same as A{:}, namely, a comma-separated list of the contents of the cell array. However, since subsref is a function, you need to specify how many outputs you want; by default it only provides the first one. Compare:

>> A = {'xy', [10 20 30]};

>> A{:}
ans =
    'xy'
ans =
    10    20    30

>> subsref(A,substruct('{}',{':'}))
ans =
    'xy'

>> [a, b] = subsref(A,substruct('{}',{':'}))
a =
    'xy'
b =
    10    20    30
1
Edric On

The "problem" here (if there is one) is that there is no single variable in MATLAB that can hold all the elements of a comma-separated list. Following on from @Luis' answer, you could do this:

A = {'xy', [10 20 30]};
[x{1:numel(A)}] = subsref(A, substruct('{}', {':'}))

but... it achieves precisely nothing, because you've just put all the elements of the comma-separated list back into a single cell array, which is precisely where you started.

So, I suppose the point is that a comma-separated list probably isn't much use to you here. What do you actually want to do?