myNewStruct = flatten_children_structs(myStruct) accepts a struct with one or more struct arrays in some its fields (child struct arrays) and brings the fields of the "child structs" up to the top level. A struct array with the same length as the child structs is returned. All fields with struct arrays must have the same number of elements. e.g. if myStruct has the following fields: field1: 34 field2: [2 3 4 5 6] field3: {'one' 'two' 'three'} field4: [1x300 struct] with fields: field5, field6, field7 the returned myNewStruct is a 1x300 struct with fields: field1: 34 (across all elements of array) field2 [2 3 4 5 6] (across all elements of array) field3 {'one' 'two' 'three'} (across all elements of array) field5: <value from field4 struct> field6: <value from field4 struct> field7: <value from field4 struct> Note that if there are child structs that are not in an array these are simply treated as a struct array of length 1 and these are flattened into the parent struct. All child struct arrays must be of the same length. 26 Jan, 2007 - First version, S.T.
0001 function myNewStruct = flatten_children_structs(myStruct) 0002 % 0003 % myNewStruct = flatten_children_structs(myStruct) 0004 % 0005 % accepts a struct with one or more struct arrays in some its 0006 % fields (child struct arrays) and brings the fields of the "child 0007 % structs" up to the top level. A struct array with the same length 0008 % as the child structs is returned. All fields with struct arrays 0009 % must have the same number of elements. 0010 % 0011 % e.g. if myStruct has the following fields: 0012 % 0013 % field1: 34 0014 % field2: [2 3 4 5 6] 0015 % field3: {'one' 'two' 'three'} 0016 % field4: [1x300 struct] with fields: field5, field6, field7 0017 % 0018 % the returned myNewStruct is a 1x300 struct with fields: 0019 % 0020 % field1: 34 (across all elements of array) 0021 % field2 [2 3 4 5 6] (across all elements of array) 0022 % field3 {'one' 'two' 'three'} (across all elements of array) 0023 % field5: <value from field4 struct> 0024 % field6: <value from field4 struct> 0025 % field7: <value from field4 struct> 0026 % 0027 % Note that if there are child structs that are not in an array 0028 % these are simply treated as a struct array of length 1 and these 0029 % are flattened into the parent struct. 0030 % 0031 % All child struct arrays must be of the same length. 0032 % 0033 % 26 Jan, 2007 - First version, S.T. 0034 0035 0036 if(~isstruct(myStruct) | length(myStruct) ~= 1 | ndims(myStruct) > 2) 0037 error('input argument must be a struct of length 1'); 0038 end 0039 0040 %obtain the fieldnames and values of myStruct 0041 myStructFieldNames = fieldnames(myStruct); 0042 myStructFieldValues = struct2cell(myStruct); 0043 0044 %go through all fields and find out which ones are structs 0045 %for those that are structs, record the lengths of the struct arrays 0046 for iField = 1:length(myStructFieldNames) 0047 fieldIsStruct(iField) = isstruct(myStruct.(myStructFieldNames{iField})); 0048 if(fieldIsStruct(iField)) 0049 fieldStructLength(iField) = length(myStruct.(myStructFieldNames{iField})); 0050 else 0051 fieldStructLength(iField) = 0; 0052 end 0053 end 0054 0055 %the lengths of all child structs must be equal 0056 if(any(diff(fieldStructLength(fieldStructLength ~= 0)) ~= 0)) 0057 error('Child struct arrays must all have the same length'); 0058 else 0059 childrenLengths = fieldStructLength(find(fieldStructLength ~= 0,1)); 0060 end 0061 0062 %obtain the indexes of the fields for the children struct arrays 0063 childStructIdxs = find(fieldIsStruct); 0064 0065 %obtain the fieldnames that are not structs 0066 myNewStructFieldNames = myStructFieldNames(~fieldIsStruct); 0067 0068 0069 for idxChildStruct = 1:childrenLengths 0070 %obtain the values for fields that are not structs 0071 myNewStructFieldValues = myStructFieldValues(~fieldIsStruct); 0072 0073 %construct the new struct array, going through each element of 0074 %the child struct arrays 0075 for ichildStruct = childStructIdxs 0076 childStructName = myStructFieldNames{ichildStruct}; 0077 tmpChildStruct = myStruct.(childStructName); 0078 childStructFieldNames = fieldnames(tmpChildStruct); 0079 0080 childStructFieldValues = struct2cell(tmpChildStruct(idxChildStruct)); 0081 0082 0083 0084 0085 0086 if(idxChildStruct == 1) 0087 myNewStructFieldNames = {myNewStructFieldNames{:} childStructFieldNames{:}}; 0088 end 0089 0090 0091 myNewStructFieldValues = {myNewStructFieldValues{:} childStructFieldValues{:}}; 0092 0093 0094 end 0095 0096 newStructParams = cell(1,length(myNewStructFieldNames)*2); 0097 newStructParams(1:2:end) = myNewStructFieldNames; 0098 newStructParams(2:2:end) = myNewStructFieldValues; 0099 myNewStruct(idxChildStruct) = cell2struct(myNewStructFieldValues,myNewStructFieldNames,2); 0100 end 0101 0102 return