How can I access a field of a struct, if I have a cell-Array containing all the subfields?

5 views (last 30 days)
I have some problem with a variant control mechanism I need for a simulation.
Suppose I have a struct (named data) that has various fields, possibly containing subfields.
For example: data.car.speed = 10, data.car.color = 'white', data.duration = 1000, data.format = 'A4' etc.
For my variants i have another struct var, that has some of the fields of data that I want to change
For example: var.car.speed = 20, var.duration = 100
In my original simulation I want to have the original data-struct, in my variant1-simulation I want to have a struct of the same composition but with the var-values
For this example: temp_data.car.speed = 20, temp_data.car.color = 'white', temp_data.duration = 100, temp_data.format = 'A4'
It should be noted that I want to use fields and subsequent subfields however I please, so I dont want to be limited by a fixed struct.
I have a working function that utilizes recursion, but it also uses the dreaded eval-function that I like to avoid whenever possible.
function temp_data = include_variants(data, var)
temp_data = data;
var_toplevel_field = fieldnames(var);
for i = 1:length(var_toplevel_field)
if ~isempty(var.(var_toplevel_field{i}))
temp_data = rekursive_add(temp_data, var, var_toplevel_field(i));
end
end
end
function temp_data = rekursive_add(temp_data, var, field_path)
temp_var = var;
for i = 1:length(field_path)
temp_var = temp_var.(field_path{i});
end
try
next_fields = fieldnames(temp_var);
for j = 1:length(next_fields)
temp_data = rekursive_add(temp_data, var, [field_path next_fields{j}]);
end
catch
str = 'temp_data';
for i = 1:length(field_path)
str = [str '.' field_path{i}];
end
str = [str ' = temp_var;'];
eval(str)
end
end
Can anyone think of a way to get this functionality without using eval?

Accepted Answer

Steven Lord
Steven Lord on 4 Dec 2020
data.car.speed = 10;
data.car.color = 'white';
data.duration = 1000;
data.format = 'A4'
data = struct with fields:
car: [1×1 struct] duration: 1000 format: 'A4'
pathToField = {'car', 'speed'};
S = getfield(data, pathToField{:})
S = 10
data = setfield(data, pathToField{:}, 42);
disp(data.car)
speed: 42 color: 'white'

More Answers (0)

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2016a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!