Rename a Field in a Structure Array

I'm Matthew Simoneau, a software developer at MathWorks focusing on technical communication and social computing.

My friend Bryan May, an occasional MATLAB programmer, called me with a question the other day. He was working with a structure array and wanted to rename one of the fields. My scan of the documentation came up empty. MATLAB has a setfield and a rmfield, but not a "rename field". This started me thinking about the best way to implement this in MATLAB.

Create a Sample Structure Array

First, lets create a simple structure array.

clear a
a(1).foo = 1;
a(1).bar = 'one';
a(2).foo = 2;
a(2).bar = 'two';
a(3).foo = 3;
a(3).bar = 'three';
disp(a)
1x3 struct array with fields:
foo
bar


Using STRUCT2CELL and CELL2STRUCT

The first technique that came to mind was to use the combination of struct2cell and cell2struct. Here we convert the structure to two cell arrays, one containing the fieldnames f and one containing the values v. We find the field in f and rename it, then put the structure back together.

f = fieldnames(a);
v = struct2cell(a);
f{strmatch('bar',f,'exact')} = 'baz';
a = cell2struct(v,f);
disp(a)
1x3 struct array with fields:
foo
baz


Using List Expansions and DEAL

Thinking a bit more, I came up with a way to do this a bit more "in place". Comma-separated list expansion is a powerful concept in MATLAB. I knew I could generate one with the a(:).baz notation, and that I could use deal to assign them back into another comma-separated list.

[a(:).qux] = deal(a(:).baz);
a = rmfield(a,'baz');
disp(a)
1x3 struct array with fields:
foo
qux


No DEAL Required

Scott French pointed out to me that, as of MATLAB 7, the deal was no longer necessary.

[a.quux] = a.qux;
a = rmfield(a,'qux');
disp(a)
1x3 struct array with fields:
foo
quux


Generalization

Further, Kenneth Eaton commented that this technique generalizes nicely using dynamic field names, introduced in MATLAB 6.5.

oldField = 'quux';
newField = 'corge';
[a.(newField)] = a.(oldField);
a = rmfield(a,oldField);
disp(a)
1x3 struct array with fields:
foo
corge


Conclusion

My guess is that the no-deal technique used in the last two sections is the most efficient in most circumstances, though I haven't done any profiling. The code is certainly the cleanest in these. What do you think? Is there a better way? Let me know here.

Published with MATLAB® 7.10

|