1
## Copyright (C) 2006-2013 Paul Kienzle
3
## This file is part of Octave.
5
## Octave is free software; you can redistribute it and/or modify it
6
## under the terms of the GNU General Public License as published by
7
## the Free Software Foundation; either version 3 of the License, or (at
8
## your option) any later version.
10
## Octave is distributed in the hope that it will be useful, but
11
## WITHOUT ANY WARRANTY; without even the implied warranty of
12
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
## General Public License for more details.
15
## You should have received a copy of the GNU General Public License
16
## along with Octave; see the file COPYING. If not, see
17
## <http://www.gnu.org/licenses/>.
20
## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1})
21
## @deftypefnx {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
22
## Return a copy of @var{s1} with fields arranged alphabetically or as
23
## specified by @var{s2}.
25
## Given one struct, arrange field names in @var{s1} alphabetically.
27
## If the second argument is a struct, arrange field names in @var{s1} as they
28
## appear in @var{s2}. The second argument may also specify the order in a
29
## permutation vector or a cell array of strings containing the fieldnames of
30
## @var{s1} in the desired order.
32
## The optional second output argument @var{p} is assigned the permutation
33
## vector which converts the original name order into the new name order.
39
## s = struct ("d", 4, "b", 2, "a", 1, "c", 3);
40
## t1 = orderfields (s)
50
## t = struct ("d", @{@}, "c", @{@}, "b", @{@}, "a", @{@});
51
## t2 = orderfields (s, t)
61
## t3 = orderfields (s, [3, 2, 4, 1])
71
## [t4, p] = orderfields (s, @{"d", "c", "b", "a"@})
87
## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
90
## Author: Paul Kienzle <pkienzle@users.sf.net>
93
function [t, p] = orderfields (s1, s2)
95
if (nargin == 1 || nargin == 2)
97
error ("orderfields: S1 must be a struct");
104
## One structure: return the fields in alphabetical order.
106
names = sort (fieldnames (s1));
110
## Two structures: return the fields in the order of s2.
111
names = fieldnames (s2);
112
if (! isequal (sort (fieldnames (s1)), sort (names)))
113
error ("orderfields: structures do not have the same fields");
115
elseif (iscellstr (s2))
116
## A structure and a list of fields: order by the list of fields.
117
t1 = sort (fieldnames (s1));
119
if (! isequal (t1, t2))
120
error ("orderfields: name list does not match structure fields");
123
elseif (isvector (s2))
124
## A structure and a permutation vector: permute the order of s1.
125
names = fieldnames (s1);
128
t2 = 1:numel (names);
129
if (! isequal (t1, t2))
130
error ("orderfields: invalid permutation vector");
136
## Corner case of empty struct
142
## Find permutation vector which converts the original name order
143
## into the new name order. Note: could save a couple of sorts
144
## in some cases, but performance isn't critical.
147
[~, oldidx] = sort (fieldnames (s1));
148
[~, newidx] = sort (names);
152
## Permute the names in the structure.
154
args = cell (1, 2 * numel (names));
155
args(1:2:end) = names;
156
args(2:2:end) = {[]};
157
t = struct (args{:});
160
for i = 1:numel (names)
162
[t(1:n).(el)] = s1(:).(el);
164
## inherit dimensions
165
t = reshape (t, size (s1));
172
%! a = struct ("foo", {1, 2}, "bar", {3, 4});
173
%! b = struct ("bar", 6, "foo", 5);
174
%! c = struct ("bar", {7, 8}, "foo", 9);
176
%! a(2) = orderfields (b, a);
177
%! assert (a(2).foo, 5);
178
%! assert (a(2).bar, 6);
180
%! [a(2), p] = orderfields (b, [2 1]);
181
%! assert (a(2).foo, 5);
182
%! assert (a(2).bar, 6);
183
%! assert (p, [2; 1]);
185
%! a(2) = orderfields (b, fieldnames (a));
186
%! assert (a(2).foo, 5);
187
%! assert (a(2).bar, 6);
189
%! a(1:2) = orderfields (c, fieldnames (a));
190
%! assert (a(2).foo, 9);
191
%! assert (a(2).bar, 8);
199
%! aa(2) = orderfields (bb, aa);
200
%! assert (aa(2).x, 8);
201
%! assert (aa(2).y{1}, 6);
203
## Corner case of empty struct, bug #40224
204
%!assert (orderfields (struct ()), struct ())