7017
|
1 ## Copyright (C) 2006, 2007 Paul Kienzle |
5881
|
2 ## |
|
3 ## This file is part of Octave. |
|
4 ## |
|
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 |
7016
|
7 ## the Free Software Foundation; either version 3 of the License, or (at |
|
8 ## your option) any later version. |
5881
|
9 ## |
|
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. |
|
14 ## |
|
15 ## You should have received a copy of the GNU General Public License |
7016
|
16 ## along with Octave; see the file COPYING. If not, see |
|
17 ## <http://www.gnu.org/licenses/>. |
5881
|
18 |
|
19 ## -*- texinfo -*- |
6713
|
20 ## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2}) |
5881
|
21 ## Return a struct with fields arranged alphabetically or as specified |
|
22 ## by @var{s2} and a corresponding permutation vector. |
|
23 ## |
|
24 ## Given one struct, arrange field names in @var{s1} alphabetically. |
|
25 ## |
|
26 ## Given two structs, arrange field names in @var{s1} as they appear |
|
27 ## in @var{s2}. The second argument may also specify the order in |
|
28 ## a permutation vector or a cell array of strings. |
|
29 ## |
|
30 ## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct} |
|
31 ## @end deftypefn |
|
32 |
|
33 ## Author: Paul Kienzle <pkienzle@users.sf.net> |
|
34 ## Adapted-By: jwe |
|
35 |
|
36 function [t, p] = orderfields (s1, s2) |
|
37 |
|
38 if (nargin == 1 || nargin == 2) |
|
39 if (! isstruct (s1)) |
|
40 error ("orderfields: expecting argument to be a struct"); |
|
41 endif |
|
42 else |
|
43 print_usage (); |
|
44 endif |
|
45 |
|
46 if (nargin == 1) |
|
47 ## One structure: return the fields in alphabetical order. |
6862
|
48 if (isstruct (s1)) |
5881
|
49 names = sort (fieldnames (s1)); |
|
50 endif |
|
51 elseif (nargin == 2) |
6862
|
52 if (isstruct (s2)) |
5881
|
53 ## Two structures: return the fields in the order of s2. |
|
54 names = fieldnames (s2); |
|
55 if (! isequal (sort (fieldnames (s1)), sort (names))) |
5887
|
56 error ("orderfields: structures do not have same fields"); |
5881
|
57 endif |
|
58 elseif (iscellstr (s2)) |
|
59 ## A structure and a list of fields: order by the list of fields. |
|
60 t1 = sort (fieldnames (s1)); |
|
61 t2 = sort (s2(:)); |
|
62 if (! isequal (t1, t2)) |
5887
|
63 error ("orderfields: name list does not match structure fields"); |
5881
|
64 endif |
|
65 names = s2; |
|
66 elseif (isvector (s2)) |
|
67 ## A structure and a permutation vector: permute the order of s1. |
|
68 names = fieldnames (s1); |
|
69 t1 = sort (s2); |
|
70 t1 = t1(:)'; |
6862
|
71 t2 = 1:numel (names); |
5881
|
72 if (! isequal (t1, t2)) |
|
73 error ("orderfields: invalid permutation vector"); |
|
74 endif |
6862
|
75 names = names (s2); |
5881
|
76 endif |
|
77 endif |
|
78 |
|
79 ## Find permutation vector which converts the original name order |
|
80 ## into the new name order. Note: could save a couple of sorts |
|
81 ## in some cases, but performance isn't critical. |
|
82 |
|
83 if (nargout == 2) |
|
84 [oldel, oldidx] = sort (fieldnames (s1)); |
|
85 [newel, newidx] = sort (names); |
|
86 p = oldidx(newidx); |
|
87 endif |
|
88 |
|
89 ## Permute the names in the structure. |
6862
|
90 if (numel (s1) == 0) |
|
91 args = cell (1, 2 * numel (names)); |
|
92 args(1:2:end) = names; |
|
93 args{2:2:end} = {}; |
|
94 t = struct (args{:}); |
|
95 else |
|
96 for i = 1:numel (names) |
|
97 el = names(i); |
|
98 t(:).(el) = s1(:).(el); |
|
99 endfor |
|
100 endif |
5881
|
101 |
|
102 endfunction |