Home > utils > flatten_children_structs.m

flatten_children_structs

PURPOSE ^

SYNOPSIS ^

function myNewStruct = flatten_children_structs(myStruct)

DESCRIPTION ^

 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.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003