
Structures
Structures are arrays!
Structures are the Matlab version of the hash table. But many programmers forget that they are not just an associative table, they are an array of associative tables.
Here is a schematic comparison between arrays and structures:

In practice, one can then define many elements in a structure array:
>> S = struct('Hello', 'world!', 'answer', 42); % Defines the fields of the structure for the first element
>> size(S)
ans =
1 1
>> S(2,3).Hello = 'Dolly'; % Index the structure S as a regular array
>> size(S)
ans =
2 3
Note that in this exemple all the non-assigned elements contain empty fields:
>> S(2,2) % Also holds with elements (1,2), (1,3) and (2,1)
ans =
struct with fields:
Hello: []
answer: []
Defining fields of an empty structure
To define an empty structure, many people do the following:
>> S = struct('a', [], 'b', [])
S =
struct with fields:
a: []
b: []
this syntax is correct (it doesn't generate an error) but does not exactly create an empty strucure: it defines a structure with fields containing empty arrays. The best evidence that the structure
>> size(S)
ans =
1 1
To create a truly empty structure, one has to use empty cells
>> S = struct('a', {}, 'b', {})
S =
0×0 empty struct array with fields:
a
b
>> size(S)
ans =
0 0
And in the case you don't want an empty structure but want to assign empty cells to all the fields? Then the kind-of-awkward following syntax has to be employed:
>> S = struct('a', {{}}, 'b', {{}})
S =
struct with fields:
a: {}
b: {}
Calling structure fields dynamically
Let's continue playing with structures. The syntax to dynamically call the field
S.(fieldname)
If you're asking yourself how this could be useful, imagine that you have the following structure:
S =
struct with fields:
small: 2
large: 1024
huge: 100000
and that you want to select one of the fields at random. Then all you have to do is:
>> F = fieldnames(S); % F contains the field names {'small', 'large', 'huge'}
>> i = randi(numel(F)); % Select an index at random, here i=3
>> S.(F{i})
ans =
100000
Extracting all the values of a given field
Have a structure containing many elements with different fields, one may want to isolate all the values of a given field in an array. Of course one can use a loop for this, but the following syntax is more elegant:
A = [S(:).field];
The principle is simple: take all elements columnwise with
A classical exemple is when you want to filter out objects of a black and white image after a segmentation with
On the speed side, this syntax is much more efficient than a foor loop. Consider for instance the following exemple:
% Define a structure with fields x and y containing each a vector of 100 random values
S = struct('x', mat2cell(rand(100,1), ones(100,1), 1), 'y', mat2cell(rand(100,1), ones(100,1), 1));
% Extracting the 'x' vector with a loop
tic
A = NaN(numel(S),1);
for i = 1:numel(S)
A(i) = S(i).x;
end
toc % Elapsed time is 0.033700 seconds.
% Using the smart syntax
tic;
A = [S(:).x];
toc % Elapsed time is 0.000272 seconds. 120 times faster !
Comments
There are no comments on this post so far. Write a comment.