-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetfields.m
More file actions
102 lines (94 loc) · 3.46 KB
/
setfields.m
File metadata and controls
102 lines (94 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
%setfields Add Field-Value pairs to structure
%
%S = setfields(S0,'field1',value1,'field2',value2,...)
%S = setfields(S0,{'field1',value1,'field2',value2,...})
%S = setfields(S0,'{'field1','field2',...},{value1,value2,...})
%S = setfields(S0,S1)
% where S1 = struct('field1',value1,'field2',value2,...)
%
%sets the field-value pairs in the structure S0, and errors if the fields
%do not exist. The values value1, value2 etc. will be assigned to the
%fields field1, field2, etc in the structure S0, and returned as S. The
%field-value pairs may be specified as arguments, cell arrays, or a
%structure
%
%Modification History
%Created 2011.05.19 Peter Hollender
% 2014.04.16 Added recursive structure adding
%
% See also fieldnames getfield setfield rmfield orderfields
function s = setfields(s0,varargin)
s = s0;
if nargin == 1 % Pass through
%
elseif nargin == 2 && isstruct(varargin{1}) % Structure
s1 = varargin{1};
tgtfields = fieldnames(s1);
for i = 1:length(tgtfields)
tgtfield = tgtfields{i};
s = setfields(s,tgtfield,s1.(tgtfield));
end
elseif nargin == 3 && iscell(varargin{1}) && iscell(varargin{2}) % Cell of parameters, cell of values
tgtfields = varargin{1};
values = varargin{2};
for i = 1:length(tgtfields)
tgtfield = tgtfields{i};
s = setfields(s,tgtfield,values{i});
end
elseif nargin == 2 && iscell(varargin{1}) && length(varargin{1})==1 %Cell of other inputs
s = setfields(s,varargin{1}{1});
elseif nargin == 2 && iscell(varargin{1}) && mod(length(varargin{1}),2) == 0 %Cell {P1,V1,P2,V2...}
tgtfields = varargin{1}(1:2:end);
values = varargin{1}(2:2:end);
for i = 1:length(tgtfields)
tgtfield = tgtfields{i};
s = setfields(s,tgtfield,values{i});
end
elseif mod(nargin,2) % P1,V1,P2,V2,...
tgtfields = varargin(1:2:end);
values = varargin(2:2:end);
for i = 1:length(tgtfields)
tgtfield = tgtfields{i};
dots = strfind(tgtfield,'.');
if isempty(dots)
s = caseInsensitiveAdd(s,tgtfield,values{i});
else
subfield = tgtfield(dots(1)+1:end);
tgtfield = tgtfield(1:dots(1)-1);
fields = fieldnames(s);
matchi = find(strcmpi(fields,tgtfield));
match = find(strcmp(fields,tgtfield));
if isempty(match)
warning(sprintf('Case-Insensitive Match for structure ''%s'' found. Assigning value specified for ''%s'' to ''%s''',fields{matchi},tgtfield,fields{matchi}));
tgtfield = fields{matchi};
end
if ~isfield(s,tgtfield)
error('%s is not a field',tgtfield);
s.(tgtfield) = struct;
end
s.(tgtfield) = setfields(s.(tgtfield),subfield,values{i});
end
end
else %Invalid Syntax
error('Unable to parse field-value pairs')
end
end
function s = caseInsensitiveAdd(s0,tgtfield,value)
s = s0;
fields = fieldnames(s0);
match = find(strcmp(fields,tgtfield));
matchi = find(strcmpi(fields,tgtfield));
if isempty(matchi)
error('Field ''%s'' not found',tgtfield);
s.(tgtfield) = value;
else
if isempty(match)
warning(sprintf('Case-Insensitive Match for option ''%s'' found. Assigning value specified for ''%s'' to ''%s''',fields{matchi},tgtfield,fields{matchi}));
end
if isstruct(value) && isstruct(s.(fields{matchi}))
s.(fields{matchi}) = setfields(s.(fields{matchi}),value);
else
s.(fields{matchi}) = value;
end
end
end