Reputation: 411
I want to count all elements in a cell array, including those in "nested" cells.
For a cell array
>> C = {{{1,2},{3,4,5}},{{{6},{7},{8}},{9}},10}
C = {1x2 cell} {1x2 cell} [10]
The answer should be 10
.
One way is to use [C{:}]
repeatedly until there are no cells left and then use numel
but there must be a better way?
Upvotes: 7
Views: 5428
Reputation: 124553
Since you are only interested in the number of elements, here is a simplified version of flatten.m that @Ansari linked to:
function n = my_numel(A)
n = 0;
for i=1:numel(A)
if iscell(A{i})
n = n + my_numel(A{i});
else
n = n + numel(A{i});
end
end
end
The result:
>> C = {{{1,2},{3,4,5}},{{{6},{7},{8}},{9}},10};
>> my_numel(C)
ans =
10
If you are feeling lazy, we can let CELLPLOT do the counting:
hFig = figure('Visible','off');
num = numel( findobj(cellplot(C),'type','text') );
close(hFig)
Basically we create an invisible figure, plot the cell array, count how many "text" objects were created, then delete the invisible figure.
This is how the plot looks like underneath:
Upvotes: 9
Reputation: 8218
Put this in a function (say flatten.m
) (code from MATLAB Central):
function C = flatten(A)
C = {};
for i=1:numel(A)
if(~iscell(A{i}))
C = [C,A{i}];
else
Ctemp = flatten(A{i});
C = [C,Ctemp{:}];
end
end
Then do numel(flatten(C))
to find the total number of elements.
If you don't like making a separate function, you can employ this clever (but nasty) piece of code for defining a flatten function using anonymous functions (code from here):
flatten = @(nested) feval(Y(@(flat) @(v) foldr(@(x, y) ifthenelse(iscell(x) | iscell(y), @() [flat(x), flat(y)], @() {x, y}), [], v)), nested);
Either way, you need to recurse to flatten the cell array then count.
Upvotes: 2