# Working with Arrays of Structures

Though I have covered this topic somewhat in the past, it seems like a good time to refresh the information. There are recent posts on the MATLAB newsgroup relating to this topic such as this one.

### Original Question

Suppose I have a structure array and want to find all the entries with a value of 4, without looping, something like [m,n] = find(f.h == 4).

f(1).h = [1 2 3 4];
f(2).h = [5 6 7 8];
try
[m,n] = find(f.h == 4);
end

Why can't I use the find statement directly? Let's take a look at the error message to understand.

lerr = lasterror;
disp(lerr.message)
Error using ==> eq
Too many input arguments.


Too many input arguments? What is f.h? For that matter, what exactly is f again?

f
f =
1x2 struct array with fields:
h


f is a struct array, and f.h is a comma-separated list.

f.h
ans =
1     2     3     4
ans =
5     6     7     8


### Alternatives

To turn this list into a MATLAB construct I can use, I'd normally either wrap it inside [] or {}. If I wrap f.h inside [], I lose the information about what is in the first element of f and what is in the second.

[f.h]
ans =
1     2     3     4     5     6     7     8


Wrapping f.h inside {}, I have a cell array to work with.

{f.h}
ans =
[1x4 double]    [1x4 double]


I still can't immediately use find or numeric functions on this array.

try
[m,n] = find({f.h} == 4);
end
lerr = lasterror;
disp(lerr.message)
Error using ==> evalin
Undefined function or method 'eq' for input arguments of type 'cell'.


### Solution

What I'd like is a way to work with my struct, without writing too much code, without looping, that is ideally a pattern I can reuse as my problem evolves. This is exactly what arrayfun was designed to help with. It works on each element of an array, and I need to just tell it what I want to operate on one element, as well as telling arrayfun what array to work on.

Let's first find the values in the struct array f equal to 4. Since I have 2 arrays embedded in f, and they may each have different numbers of outputs, I have to clearly state that the outputs need to go into a cell array.

[m,n] = arrayfun(@(x)find(x.h==4),f,'uniformoutput',false)
m =
[1]    [1x0 double]
n =
[4]    [1x0 double]


This becomes even more obvious if I can another array, g that is even less "regular" than f.

g = f;
g(3).h = [1 2 17 4];
g(4).h = [1 3 17 5 9 17];
[mg,ng] = arrayfun(@(x)find(x.h==17),g,'uniformoutput',false)
mg =
[1x0 double]    [1x0 double]    [1]    [1x2 double]
ng =
[1x0 double]    [1x0 double]    [3]    [1x2 double]


Some problems are more benign however and it would be wasteful to return results in a cell array and then have to unpack them into a numeric array, for example, the function max, which generally has a single value as the result.

[minval,idx] = arrayfun(@(x)max(x.h),f)
[minval,idx] = arrayfun(@(x)max(x.h),g)
minval =
4     8
idx =
4     4
minval =
4     8    17    17
idx =
4     4     3     3


### Related Topics

Here are some links to related blogs and MATLAB reference pages.

• Do you use struct arrays?
• If yes, do you use arrayfun, or do you use loops? Whichever your choice is, can you say more about why it's your choice?
• Do you avoid struct arrays all together and use something else? If so, what data representations do you use instead?