I'd like to achieve the following using dynamic fieldnames instead of setfield:
Say a struct 'myStruct' has a set of nested structures, i.e.
myStruct.a.b.c = 0
myStruct.a.d = 0
myStruct.a.e.f.g = 0
I want to be able to flexibly set the leaf structure values as follows:
fields = {'a', 'b', 'c'}
paramVal = 1
setfield(myStruct, fields{:}, paramVal)
This works using setfield. Is there a syntax that will do this using dynamic fieldnames? The following obviously doesn't work because the fieldname needs to be a string not an array, but demonstrates what I want:
myStruct.(fields{:}) = 0
Which would be equivalent to:
myStruct.('a').('b').('c') = 0
Recursive solution without eval, ripped from one of my old utility functions:
function s = setsubfield(s, fields, val)
if ischar(fields)
fields = regexp(fields, '\.', 'split'); % split into cell array of sub-fields
end
if length(fields) == 1
s.(fields{1}) = val;
else
try
subfield = s.(fields{1}); % see if subfield already exists
catch
subfield = struct(); % if not, create it
end
s.(fields{1}) = setsubfield(subfield, fields(2:end), val);
end
I guess the try/catch can be replaced with if isfield(s, fields{1}) ..., I don't remember why I coded it like that.
Usage:
>> s = struct();
>> s = setsubfield(s, {'a','b','c'}, 55);
>> s = setsubfield(s, 'a.b.d.e', 12)
>> s.a.b.c
ans =
55
>> s.a.b.d.e
ans =
12
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With