Cell arrays
A cell array is a MATLAB container whose elements may be arrays of any class and any shape. Where a numeric matrix demands homogeneity — every entry is, say, a double — a cell array imposes nothing. The mechanism is the canonical way to store a list of strings of unequal length, a heterogeneous record, or a variable-length argument list. The class is cell; the constructor is curly braces { }; indexing uses both () (subset of the cell array) and {} (contents of cells).
Constructing cell arrays
c = {1, "two", [3 4 5], magic(3)};
size(c) % [1 4]
class(c) % 'cell'
Each cell contains an independent array. The shape of the cell array itself (here 1×4) is independent of the shape of the contents. A 2-d cell array uses semicolons or newlines:
C = {1, "row"; [1 2 3], magic(2)}
% 2×2 cell:
% [1] ["row"]
% [1 2 3] [2×2 double]
An empty cell of size M×N is built by cell(m, n). The function cell(0, 0) returns the canonical empty cell {}.
The two indexing forms
The most important fact about cell arrays is the distinction between () and {}:
| Form | Yields | Result class |
|---|---|---|
c(i) | A 1×1 cell containing the i-th cell | cell |
c{i} | The contents of the i-th cell | The class of the contents |
c = {1, "two", [3 4 5]};
c(2) % {"two"} (a 1×1 cell)
c{2} % "two" (the string)
class(c(2)) % 'cell'
class(c{2}) % 'string'
The () form is appropriate when re-shaping a cell array — selecting a subset, reordering, transposing. The {} form is appropriate when extracting the contents for use in a computation. The reader of MATLAB learns the distinction by example; the most-cited mistake is using c(2) + 1 and being puzzled by the resulting error.
Comma-separated lists
The brace expansion c{:} produces a comma-separated list — not a single value, but a sequence of values that the caller may consume. Three principal uses:
As a variable-length argument list. A function called with f(c{:}) receives the contents of the cells as separate arguments:
args = {0, 2*pi, 100};
linspace(args{:}) % equivalent to linspace(0, 2*pi, 100)
Concatenated into an array. [c{:}] concatenates the contents horizontally; [c{:}].' then turns them into a column:
c = {1, 2, 3};
[c{:}] % [1 2 3]
As multiple return values. [a, b, c] = deal(c{:}) distributes the cells into separate variables; deal is the canonical helper.
varargin and varargout
A function declared with the special parameter varargin receives any extra trailing arguments as a cell array. Symmetrically, varargout is a cell of output values:
function info = describe(varargin)
info = sprintf("%d arguments\n", nargin);
for k = 1:nargin
info = info + sprintf(" arg %d: %s\n", k, class(varargin{k}));
end
end
describe(1, "two", [3 4 5])
% "3 arguments
% arg 1: double
% arg 2: string
% arg 3: double"
The mechanism is the basis of essentially every variadic function in the standard library.
Iterating cells
A for loop over a cell array binds the loop variable to the contents of each cell in turn — except that the assignment is to a 1×1 cell rather than the inner contents. The idiom is:
c = {"alpha", "beta", "gamma"};
for k = 1:numel(c)
disp(c{k}) % brace to extract
end
The higher-order function cellfun applies a function to each cell and returns either a numeric array (the default) or, with the 'UniformOutput', false option, a cell array of results:
lengths = cellfun(@strlength, ["alpha", "beta", "gamma"])
% [5 4 5]
upper_cells = cellfun(@upper, c, 'UniformOutput', false)
% {"ALPHA", "BETA", "GAMMA"}
The 'UniformOutput' distinction is one of MATLAB’s more idiomatic conveniences: it lets the same function return scalar-per-cell or a cell of varied-shape outputs.
Cells in practice
The conventional uses of cell arrays are limited but important:
- A list of strings of differing length. Before R2016b this was the only way to store such a list; today a
stringarray is usually preferred. Cells remain common in legacy code and in interfaces that have not migrated. - An argument list. A cell
{a, b, c}passed asf(args{:})is the canonical variadic-argument idiom. - A heterogeneous record. A cell with a fixed convention for each slot —
{name, age, address}— was once a common record type; todaystructandtableare preferred. - The output of certain library functions.
regexp(..., 'tokens')returns a cell of cells;strsplitreturns a cell of strings;fieldnames(s)returns a cell of field names.
Cell vs string array
A string array (introduced R2016b) is in many cases a drop-in replacement for a cell of char arrays. The two are not the same: a string array has a shape (rows and columns), each element is a single string, and == is string equality. A cell of strings has cells (each containing an independent array) and is less efficient for the common case of “a list of strings”.
sa = ["alpha", "beta", "gamma"] % string array
ca = {'alpha', 'beta', 'gamma'} % cell of char arrays
sa(2) % "beta"
ca{2} % 'beta'
sa == "beta" % [false true false]
strcmp(ca, 'beta') % [0 1 0]
The general recommendation in new code is to prefer string arrays for text; cell arrays remain the right choice when the contents are heterogeneous.
Memory and copies
A cell array is itself an array of pointers; the contents of each cell are stored separately. Assigning a cell array to a new variable shares the outer structure under copy-on-write; modifying a cell triggers a copy of the affected cell. The mechanism is efficient for cells of large arrays.
c = {large_matrix};
d = c; % shares
d{1}(1, 1) = 0; % copies only the first cell's contents