-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakeNestedStruct.m
More file actions
97 lines (88 loc) · 2.96 KB
/
makeNestedStruct.m
File metadata and controls
97 lines (88 loc) · 2.96 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
function s = makeNestedStruct(s, splitter, varargin)
% 1) s = makeNestedStruct(s, splitter, names, values )
% 2) s = makeNestedStruct(s, splitter[, nameX, valueX]* )
%
% Transforms tokenizable strings in nested structure and assigns values.
%
% INPUT SYNTAX 1)
% s --> initial struct to be modified or []
% splitter --> string used as splitter to tokenize
% names --> cell array of tokenizable strings to be processed
% values --> cell array of values to be assigned
%
% INPUT SYNTAX 2)
% s --> initial struct to be modified or []
% splitter --> string used as splitter to tokenize
% [nameX, valueX]* --> name-value-pairs of tokenizable strings and associated value
%
% OUTPUT s --> modified structure with nested structs/fields
%
% Example:
% names = { "aaa::bbb::ccc", "aaa::bbb:ddd", "aaa::ddd", "eee" };
% values = { 42, 'hi there' , 'hello' , pi };
% s = makeNestedStruct([], names, values, '::');
%
% This will create a structure with the following layout:
% s.aaa.bbb.ccc = 42
% s.aaa.bbb.ddd = 'hi there'
% s.aaa.ddd = 'hello'
% s.eee = 3.141569
%
% Note that a value field must not have a subfield:
%
% 1) The following leads to an ERROR:
% names = { "aaa::bbb", "aaa::bbb::ccc" }
% values = { 42 , 100 }
% s = makeNestedStruct([], names, values, '::')
% Error using makeNestedStruct
% Unable to perform assignment because dot indexing is not supported for variables of this type.
%
% 2) The following SILENTLY OVERWRITES an existing substructure:
% names = { "aaa::bbb::ccc", "aaa::bbb" }
% values = { 42 , 100 }
% s = makeNestedStruct([], names, values, '::')
% gives a structure s with layout
% s.aaa.bbb = 100
% as s.aaa.bbb.ccc got overwritten.
%
% Andreas Sommer, Oct2025
% code@andreas-sommer.eu
% quick return if nothing to do
if (nargin <= 2), return; end
% check which syntax is used
if iscell(varargin{1})
names = varargin{1};
values = varargin{2};
else
names = varargin(1:2:end);
values = varargin(2:2:end);
end
% error if not having right format
if ~iscell(names) || ~iscell(values)
error('Invalid call. See documentation for proper usage.')
end
% quick return if nothing to do
if length(names) == 0, return; end
% allow using [] als initializer
if ~isstruct(s) && isempty(s)
s = struct();
end
% DO THE WORK: walk through names
for i = 1:numel(names)
parts = strsplit(names{i}, splitter);
currStruct = s;
sref = struct('type', '.', 'subs', '');
for j = 1:numel(parts)-1
sref(j).type = '.';
sref(j).subs = parts{j};
if ~isfield(currStruct, parts{j})
currStruct.(parts{j}) = struct();
end
currStruct = currStruct.(parts{j});
end
% assign value to deepest field
sref(numel(parts)).type = '.';
sref(numel(parts)).subs = parts{end};
s = subsasgn(s, sref, values{i});
end
end % of function