MATLAB: How to access a field of a struct, if I have a cell-Array containing all the subfields

avoiding evalMATLABreplace struct subfields

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?

Best Answer

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'