问题
I have a 1xn struct. The structs contains some fields with numeric cells. Not every struct has the same fields. So I would like to add the missing fields to the struct. But I didn't get it.
% Mimimal example
% I have same cells, imported from csv by csv2cell()
clear
dataCell{1}={"field_a","field_b","field_c"; ...
1,2,3; ...
4,5,6};
dataCell{2}={"field_a","field_b","field_d"; ...
1,2,4; ...
4,5,8};
% Then I convert them to a struct
for ii=1:numel(dataCell)
DataStruct{ii}=cell2struct((dataCell{ii}(2:end,:)),[dataCell{ii}(1,:)],2);
try fields=[fields, fieldnames(DataStruct{ii})']; % fails for the first loop, because 'fields' doesn't exist yet
catch
fields=[fieldnames(DataStruct{ii})']; % create 'fields' in the first loop
end
end
% Create a list of all existing fields
fields=unique(fields);
% Now look for the missing fields and add them to the struct
for jj=1:numel(DataStruct)
missing_fields{jj} = setdiff(fields,fieldnames(DataStruct{jj}));
for kk=1:numel(missing_fields)
DataStruct{jj}.(missing_fields{jj}{kk})=NaN*zeros(numel(dataCell{jj}(2:end,1)),1); % Execution fails here!
end
end
This leads to an error:
Octave Error
error: invalid assignment to cs-list outside multiple assignment
error: called from:
error: ~/example.m at line 29, column 44
Matlab Error
Insufficient outputs from right hand side to satisfy comma separated
list expansion on left hand side. Missing [] are the most likely cause.
The problem is, that the output of DataStruct{1}.field_a
is not a matrix or a cell, but multiple ans. Is there a easy possibility to convert the cells to a matrix or a better possibility to import the csv?
the other good possibility would be something like this
DataStruct{jj}=setfields(missing_fields{jj},NaN_Values{jj})
where missing_fields{jj}
and NaN_Values
are both cells with the same length, so that i can set multiple fields at once.
回答1:
You use the deal
function to distribute output to inputs. For your example:
% Now look for the missing fields and add them to the struct
for jj=1:numel(DataStruct)
missing_fields{jj} = setdiff(fields,fieldnames(DataStruct{jj}));
for kk=1:numel(missing_fields)
[DataStruct{jj}.(missing_fields{jj}{kk})] = deal(NaN*zeros(numel(dataCell{jj}(2:end,1)),1));
end
end
Note that you will get an Index exceeds matrix dimensions
, but this is due to a different problem - I'm sure you'll be able to sort that one out!
回答2:
following your last question - you can use the deal command.
Snippet:
a=struct('f1',num2cell(1:10))
missing_field = 'test'
[a.(missing_field)]=deal(NaN)
来源:https://stackoverflow.com/questions/14870828/setting-multiple-fields-at-once-add-new-field-to-a-cell-struct