# Use Dynamic Field References 28

Posted by **Loren Shure**,

Use dynamic field references, the notation .(), where possible, instead of `setfield`, `getfield`, and `eval`.

### History

In MATLAB 6.5 (Release 13), we introduced dynamic field references into MATLAB. What are they and why should you use them?

In MATLAB, there are 3 basic types of arrays, traditional ones where you index using parentheses `()`, cell arrays where you can address the contents using curly braces `{}`, and structures (known in MATLAB as the type `struct`) where you access elements using the dot `.` notation.

Before R13, if you had collected information into a variable, call it `ind`, about which parts of an array you wanted to either index into or to change, you could do so using the variable in a straight-forward manner - *if* your array was a regular or cell array. By that, I mean that you could do things like:

y = x(ind) x(ind) = 17 % With cells, you typically access the contents % of one cell at a time. c{ind(1)} = x(ind(1))

However, there was no symmetry with how to accomplish the same task if your array was a `struct` and you had the fieldnames in a variable; instead you had to use `setfield` and `getfield`. There was extra overhead for accessing structure elements compared to other array types. And that's why dynamic field indexing was introduced.

### Example

#### Preferred:

fldnm = 'fred'; s.(fldnm) = 18; y = s.(fldnm)

#### Not Recommended:

s = setfield(s,'fldnm',18); y = getfield(s,'fldnm'); eval(['s.' fldnm ' = 18']); eval(['y = s.',fldnm])

### Benefits

- Speed - when you can use
`.()`, it is much faster. Part of the reason is because you don't have the overhead of calling yet another function, i.e.,`setfield`or`getfield`. An additional reason is that MATLAB can work on the structure field in place and unnecessary copies are not made. Contrast these two cases, using`setfield`and using dynamic field referencing:s = setfield(s,fldnm,3); s.(fldnm) = 3;

The first line requires at least 2 copies of the structure

`s`while the second line requires space for only one instance. - Readability -- code is easier to understand since you can see the components of the structure.
- Analyzability - programs that use
`eval`can be particularly hard to analyze, for example for dependency reports.

### Contraindications

- There are certain very complex calling sequences for
`setfield`that can't be translated into`.()`notation easily. - If you don't know the overall "structure" of your struct (e.g., all names at one "level"), it's hard to program generically with
`.()`

**Category:**- Indexing,
- Structures

### Note

Comments are closed.

## 28 CommentsOldest to Newest

**1**of 28

**2**of 28

**3**of 28

**4**of 28

**5**of 28

**6**of 28

**7**of 28

**8**of 28

test.(fname)and add whatever trailing indexing you want. --Loren

**9**of 28

**10**of 28

**11**of 28

**12**of 28

**13**of 28

**14**of 28

**15**of 28

fn = {'ref' 'doc' 'tam'}; for ind = 1:length(fn) a.(fn{ind}) = []; endI am not sure that's going to make much difference though. The contents of each field in a struct has to have contiguous memory, but the various struct fields don't have that restriction.

**16**of 28

**17**of 28

**18**of 28

**19**of 28

A.l1.l2.l3.l4 = 1234 %would like to do this: fieldname = 'l1.l2.l3.l4' %next time might be 'l1.l2' A.(fieldname) %gives: ??? Reference to non-existent field 'l1.l2.l3.l4'. A.('l1').('l2').('l3').('l4') %gives correct: 1234

**20**of 28

**21**of 28

A.L1.L2.L3...LN = value; fullString = 'L1.L2.L3...LN';is there a way to elegantly access a field given by fullString? It would be simple enough if the depth if fixed, but the only generalized way I can think is to parse the string and iteratively store substructures until the final result is obtained:

A.L1.L2.L3.L4.L5 = 12345; fullString = 'L1.L2.L3.L4.L5'; dotFind = strfind(fullString,'.'); temp = A; while ~isempty(dotFind) temp = temp.(fullString(1:dotFind(1)-1)); fullString = fullString(dotFind(1)+1:end); dotFind = strfind(fullString,'.'); end FinalAns = temp.(fullString); disp(FinalAns);While this works, it is not very elegant, efficient, or readable. fullString will change in the program. One time it may be 'L1.L2.L3'. The next it might be 'L1.M2.N3.L4'. Being somewhat new to dynamic field names (thank you, Loren for many other postings elsewhere), I had hoped/expected to just be able to use: A.(fullString) which obviously does not work.

**22**of 28

**23**of 28

A.l1.l2.l3.l4 = 1234; fieldname = 'l1.l2.l3.l4'; eval(['A.',fieldname])

**24**of 28

**25**of 28

**26**of 28

**27**of 28

**28**of 28

## Recent Comments