I have a MATLAB template structure that I'm using as a basis for a more complex output structure
conditions = {'Listen',':=:'};
items = ["apple" "duck"]; % 2 items
stims = cellstr([ ...
items, ... % text
items+".PNG", ... % picture
items+".wav" ... % sound
]);
event = struct( ...
'Cue', struct('duration',2,'jitter',0.25,'shows',conditions), ...
'Stimuli', struct('duration','sound','shows',stims), ...
'Delay', struct('duration',2,'jitter',0.25), ...
'Go', struct('duration',1,'jitter',0.25,'shows','Speak','skip','Cue==:=:'), ...
'Response', struct('duration',3,'jitter',0.25,'skip','Cue==:=:'));
events output is a 1×1 struct with the fields:
events =
1×1 struct with fields:
Cue: [1×2 struct]
Stimuli: [1×6 struct]
Delay: [1×1 struct]
Go: [1×1 struct]
Response: [1×1 struct]
I want to generate from this a 1×12 struct that contains each of the possible combinations of each top level field. Like below:
events =
1×12 struct array with fields:
Cue: [1×1 struct]
Stimuli: [1×1 struct]
Delay: [1×1 struct]
Go: [1×1 struct]
Response: [1×1 struct]
Edit: I should add that I want the output to dynamically reflect changes in the input. For example:
If the user decides to change event.Delay.duration = [1,2,3]
it would generate a struct array three times the original size, with each possible delay duration implemented
If the user decides to remove the Cue
field entirely, the output should be a struct array half the original size.
That should do the trick:
eC = struct2cell( event );
eN = fieldnames( event );
nums = cellfun( @numel, eC );
subs = cell( numel(nums), 1);
event = cell( prod(nums) , 1);
for k = 1 : prod(nums)
[ subs{:} ] = ind2sub( nums, k );
event{k} = cell2struct( cellfun(@(X,Y) X(Y), eC, subs, 'UniformOutput', false ), eN', 1 );
end
event = cat( 1, event{:} )';
Key point is the ind2sub function, which is in general helpful when dealing with multi-dimensional problems. Breaking them down to one dimension hast two advantages: 1) Nested loops are not needed. 2) We get independent from the number of dimensions.